[REV] : unwanted diff

bzr revid: aja@tinyerp.com-20140402054306-7g6g6skkqlnj6jc6
This commit is contained in:
ajay javiya (OpenERP)
2014-04-02 11:13:06 +05:30
29 changed files with 1446 additions and 516 deletions
-2
View File
@@ -288,8 +288,6 @@ class Website(openerp.addons.web.controllers.main.Home):
values = {}
if 'website_published' in _object._all_columns:
values['website_published'] = not obj.website_published
if 'website_published_datetime' in _object._all_columns and values.get('website_published'):
values['website_published_datetime'] = fields.datetime.now()
_object.write(request.cr, request.uid, [_id],
values, context=request.context)
@@ -284,10 +284,6 @@ ul.nav-stacked > li > a {
background-size: 100%;
}
section, .carousel, .parallax, .row, .hr, .blockquote {
min-height: 30px;
}
.carousel, .parallax, .blockquote {
overflow: hidden;
}
@@ -234,8 +234,6 @@ ul.nav-stacked > li > a
.oe_img_bg
background-size: 100%
section, .carousel, .parallax, .row, .hr, .blockquote
min-height: 30px
.carousel, .parallax, .blockquote
overflow: hidden
+124 -29
View File
@@ -29,6 +29,7 @@ from openerp.addons.website.models.website import slug
from openerp.osv.orm import browse_record
from openerp.tools.translate import _
from openerp import SUPERUSER_ID
from openerp.tools import html2plaintext
class QueryURL(object):
@@ -62,8 +63,8 @@ class QueryURL(object):
class WebsiteBlog(http.Controller):
_blog_post_per_page = 6
_post_comment_per_page = 6
_blog_post_per_page = 20
_post_comment_per_page = 10
def nav_list(self):
blog_post_obj = request.registry['blog.post']
@@ -129,14 +130,11 @@ class WebsiteBlog(http.Controller):
cr, uid, context = request.cr, request.uid, request.context
blog_post_obj = request.registry['blog.post']
blog_posts = None
blog_obj = request.registry['blog.blog']
blog_ids = blog_obj.search(cr, uid, [], order="create_date asc", context=context)
blogs = blog_obj.browse(cr, uid, blog_ids, context=context)
domain = []
if blog:
domain += [('blog_id', '=', blog.id)]
if tag:
@@ -176,12 +174,13 @@ class WebsiteBlog(http.Controller):
'post_url': post_url,
'date': date_begin,
}
return request.website.render("website_blog.blog_post_short", values)
response = request.website.render("website_blog.blog_post_short", values)
return response
@http.route([
'/blogpost/<model("blog.post"):blog_post>',
'/blog/<model("blog.blog"):blog>/post/<model("blog.post"):blog_post>',
], type='http', auth="public", website=True, multilang=True)
def blog_post(self, blog_post, tag_id=None, page=1, enable_editor=None, **post):
def blog_post(self, blog, blog_post, tag_id=None, page=1, enable_editor=None, **post):
""" Prepare all values to display the blog.
:param blog_post: blog post currently browsed. If not set, the user is
@@ -204,6 +203,7 @@ class WebsiteBlog(http.Controller):
- 'pager': the pager to display comments pager in a blog post
- 'tag': current tag, if tag_id
- 'nav_list': a dict [year][month] for archives navigation
- 'next_blog': next blog post , display in footer
"""
date_begin, date_end = post.get('date_begin'), post.get('date_end')
@@ -227,6 +227,10 @@ class WebsiteBlog(http.Controller):
blog_url = QueryURL('', ['blog', 'tag'], blog=blog_post.blog_id, tag=tag, date_begin=date_begin, date_end=date_end)
cr, uid, context = request.cr, request.uid, request.context
if not blog_post.blog_id.id==blog.id:
return request.redirect("/blog/%s/post/%s" % (blog_post.blog_id.id, blog_post.id))
blog_post_obj = request.registry.get('blog.post')
blog_obj = request.registry['blog.blog']
blog_ids = blog_obj.search(cr, uid, [], context=context)
blogs = blog_obj.browse(cr, uid, blog_ids, context=context)
@@ -235,53 +239,117 @@ class WebsiteBlog(http.Controller):
tag_ids = tag_obj.search(cr, uid, [], context=context)
tags = tag_obj.browse(cr, uid, tag_ids, context=context)
# Find next Post
visited_blogs = request.httprequest.cookies.get('visited_blogs') or ''
visited_ids = filter(None, visited_blogs.split(','))
visited_ids = map(lambda x: int(x), visited_ids)
if blog_post.id not in visited_ids:
visited_ids.append(blog_post.id)
next_post_id = blog_post_obj.search(cr, uid, [
('id', 'not in', visited_ids),
], order='ranking desc', limit=1, context=context)
next_post = next_post_id and blog_post_obj.browse(cr, uid, next_post_id[0], context=context) or False
values = {
'blog': blog_post.blog_id,
'blog': blog,
'blogs': blogs,
'tags': tags,
'tag': tag,
'blog_post': blog_post,
'main_object': blog_post,
'pager': pager,
'nav_list': self.nav_list(),
'enable_editor': enable_editor,
'next_post' : next_post,
'date': date_begin,
'post_url': post_url,
'blog_url': blog_url,
}
return request.website.render("website_blog.blog_post_complete", values)
response = request.website.render("website_blog.blog_post_complete", values)
response.set_cookie('visited_blogs', ','.join(map(str, visited_ids)))
request.session[request.session_id] = request.session.get(request.session_id, [])
if not (blog_post.id in request.session[request.session_id]):
request.session[request.session_id].append(blog_post.id)
# Increase counter
blog_post_obj.write(cr, SUPERUSER_ID, [blog_post.id], {
'visits': blog_post.visits+1,
},context=context)
return response
def _blog_post_message(self, user, blog_post_id=0, **post):
cr, uid, context = request.cr, request.uid, request.context
blog_post = request.registry['blog.post']
partner_obj = request.registry['res.partner']
thread_obj = request.registry['mail.thread']
website = request.registry['website']
public_id = website.get_public_user(cr, uid, context)
if uid != public_id:
partner_ids = [user.partner_id.id]
else:
partner_ids = blog_post._find_partner_from_emails(
cr, SUPERUSER_ID, 0, [post.get('email')], context=context)
if not partner_ids or not partner_ids[0]:
partner_ids = [partner_obj.create(cr, SUPERUSER_ID, {'name': post.get('name'), 'email': post.get('email')}, context=context)]
message_id = blog_post.message_post(
cr, SUPERUSER_ID, int(blog_post_id),
body=post.get('comment'),
type='comment',
subtype='mt_comment',
author_id=partner_ids[0],
discussion=post.get('discussion'),
context=dict(context, mail_create_nosubcribe=True))
return message_id
@http.route(['/blogpost/comment'], type='http', auth="public", methods=['POST'], website=True)
def blog_post_comment(self, blog_post_id=0, **post):
cr, uid, context = request.cr, request.uid, request.context
if post.get('comment'):
user = request.registry['res.users'].browse(cr, SUPERUSER_ID, uid, context=context)
group_ids = user.groups_id
group_id = request.registry["ir.model.data"].get_object_reference(cr, uid, 'website_mail', 'group_comment')[1]
if group_id in [group.id for group in group_ids]:
blog_post = request.registry['blog.post']
blog_post.check_access_rights(cr, uid, 'read')
blog_post.message_post(
cr, SUPERUSER_ID, int(blog_post_id),
body=post.get('comment'),
type='comment',
subtype='mt_comment',
author_id=user.partner_id.id,
context=dict(context, mail_create_nosubcribe=True))
user = request.registry['res.users'].browse(cr, uid, uid, context=context)
blog_post = request.registry['blog.post']
blog_post.check_access_rights(cr, uid, 'read')
self._blog_post_message(user, blog_post_id, **post)
return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
def _get_discussion_detail(self, ids, publish=False, **post):
cr, uid, context = request.cr, request.uid, request.context
values = []
mail_obj = request.registry.get('mail.message')
for message in mail_obj.browse(cr, SUPERUSER_ID, ids, context=context):
values.append({
"id": message.id,
"author_name": message.author_id.name,
"author_image": message.author_id.image and \
("data:image/png;base64,%s" % message.author_id.image) or \
'/website_blog/static/src/img/anonymous.png',
"date": message.date,
'body': html2plaintext(message.body),
'website_published' : message.website_published,
'publish' : publish,
})
return values
@http.route(['/blogpost/post_discussion'], type='json', auth="public", website=True)
def post_discussion(self, blog_post_id=0, **post):
cr, uid, context = request.cr, request.uid, request.context
publish = request.registry['res.users'].has_group(cr, uid, 'base.group_website_publisher')
user = request.registry['res.users'].browse(cr, uid, uid, context=context)
id = self._blog_post_message(user, blog_post_id, **post)
return self._get_discussion_detail([id], publish, **post)
@http.route('/blogpost/new', type='http', auth="public", website=True, multilang=True)
def blog_post_create(self, blog_id, **post):
cr, uid, context = request.cr, request.uid, request.context
create_context = dict(context, mail_create_nosubscribe=True)
new_blog_post_id = request.registry['blog.post'].create(
request.cr, request.uid, {
new_blog_post_id = request.registry['blog.post'].create(cr, uid, {
'blog_id': blog_id,
'name': _("Blog Post Title"),
'sub_title': _("Subtitle"),
'content': '',
'website_published': False,
}, context=create_context)
return werkzeug.utils.redirect("/blogpost/%s?enable_editor=1" % new_blog_post_id)
return werkzeug.utils.redirect("/blog/%s/post/%s/?enable_editor=1" % (blog_id, new_blog_post_id))
@http.route('/blogpost/duplicate', type='http', auth="public", website=True)
def blog_post_copy(self, blog_post_id, **post):
@@ -293,5 +361,32 @@ class WebsiteBlog(http.Controller):
"""
cr, uid, context = request.cr, request.uid, request.context
create_context = dict(context, mail_create_nosubscribe=True)
new_blog_post_id = request.registry['blog.post'].copy(cr, uid, blog_post_id, {}, context=create_context)
return werkzeug.utils.redirect("/blogpost/%s?enable_editor=1" % new_blog_post_id)
nid = request.registry['blog.post'].copy(cr, uid, blog_post_id, {}, context=create_context)
post = request.registry['blog.post'].browse(cr, uid, nid, context)
return werkzeug.utils.redirect("/blog/%s/post/%s/?enable_editor=1" % (post.blog_id.id, nid))
@http.route('/blogpost/get_discussion/', type='json', auth="public", website=True)
def discussion(self, post_id=0, discussion=None, count=False, **post):
cr, uid, context = request.cr, request.uid, request.context
mail_obj = request.registry.get('mail.message')
domain = [('res_id', '=', int(post_id)) ,('model','=','blog.post'), ('discussion', '=', discussion)]
#check current user belongs to website publisher group
publish = request.registry['res.users'].has_group(cr, uid, 'base.group_website_publisher')
if not publish:
domain.append(('website_published', '=', True))
ids = mail_obj.search(cr, SUPERUSER_ID, domain, count=count)
if count:
return ids
return self._get_discussion_detail(ids, publish, **post)
@http.route('/blogpsot/change_background', type='json', auth="public", website=True)
def change_bg(self, post_id=0, image=None, **post):
post_obj = request.registry.get('blog.post')
values = {'content_image' : image}
ids = post_obj.write(request.cr, request.uid, [int(post_id)], values, request.context)
return []
@http.route('/blog/get_user/', type='json', auth="public", website=True)
def get_user(self, **post):
return [False if request.session.uid else True]
@@ -2,7 +2,8 @@
<openerp>
<data noupdate="1">
<record id="blog_blog_1" model="blog.blog">
<field name="name">News</field>
<field name="name">Our News</field>
<field name="subtitle">Sharing our evolution with passion</field>
<field name="description">Presentation of new OpenERP features</field>
</record>
+415 -297
View File
@@ -13,324 +13,442 @@
<record id="blog_tag_3" model="blog.tag">
<field name="name">website</field>
</record>
<record id="blog_tag_4" model="blog.tag">
<field name="name">pos</field>
</record>
<!-- POSTS -->
<record id="blog_post_1" model="blog.post">
<field name="name">OpenERP v8 New Features</field>
<field name="name">The Future of Emails</field>
<field name="sub_title">Ideas behing the OpenERP communication tools.</field>
<field name="blog_id" ref="blog_blog_1"/>
<field name="tag_ids" eval="[(6, 0, [ref('blog_tag_1')])]"/>
<field name="website_published" eval="True"/>
<field name="website_meta_keywords">OpenERP, Point of Sale, Hardware, Interface, Payment Terminal, Store</field>
<field name="website_meta_description">Open source Point of Sale with no installation required that runs online and offline.</field>
<field name="website_meta_keywords">OpenERP, email</field>
<field name="website_meta_description">The Future of Emails</field>
<field name="content_image">/website_blog/static/src/img/post1.jpg</field>
<field name="content"><![CDATA[
<section data-snippet-id='image-text'>
<div class="container">
<div class="row">
<div class="col-md-6 mt16 mb16">
<img class="img-responsive shadow" src="/website/static/src/img/image_text.jpg"/>
</div>
<div class="col-md-6 mt16">
<p>
OpenERP's Point of Sale introduces a super clean
interface with no installation required that runs
online and offline on modern hardwares.
</p><p>
It's full integration with the company inventory
and accounting, gives you real time statistics
without the hassle of integrating several applications.
</p>
</div>
</div>
</div>
<section class="mt16 mb16 readable">
<iframe width="361" height="200" src="http://www.youtube.com/embed/EkbBFmIWoTE" frameborder="0" allowfullscreen></iframe>
<p>
Emails are broken.
</p><p>
Emails make me waste my time. But I need them.
Given the importance that emails have in our lives,
it's incredible it's still one of the only software
areas that did not evolve in the past 20 years!
</p><p>
Reading my inbox is the most unproductive task I do
on a daily basis. I have to spend one full hour a
day to process my emails. All the junk flows in the
same inbox; spams, information that doesn't matter,
quoted answers of quoted answers, etc. At the end
of the hour, only 10 emails actually requested an
answer from me. With a good tool, I could have done
my job in 10 minutes!
</p>
</section>
<section class="mt16 mb16" data-snippet-id='text-block'>
<div class="container">
<div class="row">
<div class="col-md-12 text-center mt16 mb32">
<h2>
Linked with Project Management
</h2>
<h3 class="text-muted">Infinitely flexible. Incredibly easy to use.</h3>
</div>
<div class="col-md-12 mb16 mt16">
<p>
OpenERP's <b>collaborative and realtime</b> project
management helps your team get work done. Keep
track of everything, from the big picture to the
minute details, from the customer contract to the
billing.
</p><p>
Organize projects around <b>your own processes</b>. Work
on tasks and issues using the kanban view, schedule
tasks using the gantt chart and control deadlines
in the calendar view. Every project may have it's
own stages allowing teams to optimize their job.
</p>
</div>
</div>
</div>
<section class="mt16 mb16 readable">
<p>
At OpenERP, we build tools to bring productivity to
enterprises. As emails and information flows are one of
the biggest wastes of time in companies, we have to fix
this.
</p><p>
To disrupt emails, you need more than just another user
interface. We need to rethink the whole communication flow.
</p>
<h3>The Communication Mechanism of OpenERP</h3>
<p>
Here are the ideas behing the OpenERP communication tools:
</p>
<ul>
<li>
Get Things Done: your inbox is a
todo list. You should be able to process (not only
read) the inbox and easily mark messages for future
actions. Every inbox should be empty after having
been processed; no more overload of information.
<img class="img-responsive" src="/website_blog/static/src/img/mail-sc-00.png"/>
</li><li>
Keep control of what you want to receive or don't want
to receive. People should never receive spam. You
should follow/unfollow any kind of information in one
click.
</li><li>
Productivity is key: our smart user
interface does not require you to click on every mail
to read a thread. Reading a full thread, replying,
attaching documents is super fast.
<img class="img-responsive" src="/website_blog/static/src/img/mail-sc-03.png"/>
</li><li>
A mix of push & pull: Today, people
are victims of what others decide to push to them.
OpenERP differentiates:
<ul>
<li>
Messages "for information":
you can pull them when you need some specific
information; they are not required to be read
every day.You receive only what you decided
to follow.This accounts for 90% of your daily
emails.Use the "Inbox" menu for these.
</li><li>
Messages "for action": they
require your immediate attention and you need
to process them all. This accounts for 10%
of your daily emails. Use the "To: me" menu
for these.
</li>
</ul>
</li><li>
Focus on the Content: Everything is
stripped to emphasize on the real message. No more
welcome introductions, greetings, signatures and legal
notes.We standardize the layout of each message.
(signatures are on the profile of a contact, not in
every message)
</li><li>
Folders and mailing lists are great tools but too
complex in traditional email clients. In OpenERP, a
group of contacts that share a discussion can be
created with one click. Every group should have it's
own email address.
</li>
</ul>
<p>All of this with a super sexy and minimalist user interface.</p>
</section>
<section class="oe_dark mt16 mb16" data-snippet-id='big-picture'>
<div class="container">
<div class="row">
<div class="col-md-12 text-center mt32 mb32">
<h2>Work with the hardware you already have...</h2>
</div>
<div class="col-md-12">
<img class="img-responsive" src="/website/static/src/img/big_picture.png" style="margin: 0 auto;"/>
</div>
<div class="col-md-6 col-md-offset-3 mb16 mt16">
<p class="text-center">
<b>No installation required</b>
</p>
<p class="text-center">
OpenERP's Point of Sale introduces a super clean
interface with no installation required that runs
online and offline on modern hardware. Laptops,
tablets, industrial POS, it runs on everything.
</p>
<p class="text-center">
<a href="/page/website.contactus">Get more information »</a>
</p>
</div>
</div>
</div>
</section>
]]>
</field>
</record>
<record id="blog_post_2" model="blog.post">
<field name="name">New Hardware Integration</field>
<field name="name">Integrating your CMS and E-Commerce</field>
<field name="sub_title">Building your company's website and selling your products online easy.</field>
<field name="blog_id" ref="blog_blog_1"/>
<field name="tag_ids" eval="[(6, 0, [ref('blog_tag_1')])]"/>
<field name="content">
<![CDATA[<section class="mt16 mb16" data-snippet-id='big-picture'>
<div class="container">
<div class="row">
<div class="col-md-12">
<img class="img-responsive" src="/website/static/src/img/big_picture.png" style="margin: 0 auto;"/>
</div>
<div class="col-md-6 col-md-offset-3 mb16 mt16">
<p class="text-center">
<b>New Features Launched</b>
</p>
<p class="text-center">
OpenERP's Point of Sale introduces a super clean
interface with no installation required that runs
online and offline on modern hardware. Laptops,
tablets, industrial POS, it runs on everything.
</p>
</div>
</div>
</div>
</section>
<section data-snippet-id='pricing'>
<div class="container">
<div class="row">
<div class="col-md-12 text-center mt16 mb32">
<h2>Our Offers</h2>
</div>
<div class="col-md-4">
<div class="panel panel-info">
<!-- Default panel contents -->
<div class="panel-heading text-center">
<h2 style="margin: 0">Beginner</h2>
<p style="margin: 0" class="text-muted">
Starter package
</p>
</div>
<div class="panel-body text-center text-muted" style="background-color: rgba(0,0,0,0.1)">
<h2 style="margin: 0"><span>$</span><b style="font-size: 60px">450</b><small>.00</small></h2>
<div>per month</div>
</div>
<!-- List group -->
<ul class="list-group">
<li class="list-group-item">Battery: 8 hours</li>
<li class="list-group-item">Screen: 2.5 inch</li>
<li class="list-group-item">Weight: 1.1 ounces</li>
<li class="list-group-item">No support</li>
</ul>
<div class="panel-footer text-center">
<p class="text-muted">
<i>Free shipping, satisfied or reimbursed.</i>
</p>
<a href="/page/website.contactus" class="btn btn-primary btn-lg">Order now</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-primary">
<!-- Default panel contents -->
<div class="panel-heading text-center">
<h2 style="margin: 0">Professional</h2>
<p style="margin: 0">
Enterprise package
</p>
</div>
<div class="panel-body text-center text-muted" style="background-color: rgba(0,0,0,0.1)">
<h2 style="margin: 0"><span>$</span><b style="font-size: 60px">590</b><small>.00</small></h2>
<div>per month</div>
</div>
<!-- List group -->
<ul class="list-group">
<li class="list-group-item">Battery: 12 hours</li>
<li class="list-group-item">Screen: 2.8 inch</li>
<li class="list-group-item">Weight: 1.2 ounces</li>
<li class="list-group-item">Limited support</li>
</ul>
<div class="panel-footer text-center">
<p class="text-muted">
<i>Free shipping, satisfied or reimbursed.</i>
</p>
<a href="/page/website.contactus" class="btn btn-primary btn-lg">Order now</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-info">
<!-- Default panel contents -->
<div class="panel-heading text-center">
<h2 style="margin: 0">Expert</h2>
<p style="margin: 0" class="text-muted">
The top of the top
</p>
</div>
<div class="panel-body text-center text-muted" style="background-color: rgba(0,0,0,0.1)">
<h2 style="margin: 0"><span>$</span><b style="font-size: 60px">890</b><small>.00</small></h2>
<div>per month</div>
</div>
<!-- List group -->
<ul class="list-group">
<li class="list-group-item">Battery: 20 hours</li>
<li class="list-group-item">Screen: 2.8 inch</li>
<li class="list-group-item">Weight: 1.2 ounces</li>
<li class="list-group-item">Unlimited support</li>
</ul>
<div class="panel-footer text-center">
<p class="text-muted">
<i>Free shipping, satisfied or reimbursed.</i>
</p>
<a href="/page/website.contactus" class="btn btn-primary btn-lg">Contact us</a>
</div>
</div>
</div>
</div>
</div>
</section>
]]>
</field>
</record>
<record id="blog_post_3" model="blog.post">
<field name="name">Touchscreen Point of Sale for 6.1</field>
<field name="blog_id" ref="blog_blog_1"/>
<field name="tag_ids" eval="[(6, 0, [ref('blog_tag_1'), ref('blog_tag_2')])]"/>
<field name="website_meta_keywords">Point of Sale, Hardware, Interface, Payment Terminal, Store</field>
<field name="website_meta_description">Point of Sale with no installation required that runs online and offline.</field>
<field name="content">
<![CDATA[<p>The brand new OpenERP touchscreen point of sale is available with 6.1 which allows you
to manage your shop sales very easily. It's fully web based so that you don't
have to install or deploy any software and all the sales shops can be easily
consolidated. It works in connected and disconnected modes so that you can
continue to sell even if you lose your internet connection.</p>
<img src="http://www.openerp.com/sites/default/files/fileattach/POS(2).png" alt="">
<h3>Here's a summary of its main features and benefits:</h3>
<ul>
<li>100% WEB based</li>
<li>available for any touchscreen device (ipod, ipad, any tablet)mobile (with portable devices)</li>
<li>no installation required</li>
<li>no synchronization needed, completely integrated</li>
<li>continue working even when your connection is down or if you close your browser, data won't be lost</li>
<li>fully web based with a clean interface smart interface</li>
</ul>
<p>You have different options to select your products. You can do it through the
barcode reader, just browse through the categories you have put in place (ie.
drinks, snacks, meals, etc.), or text search in case neither of the other
options work for you. For example, if you need to use the POS for your restaurant,
your employees can record multiple tickets at the same time without having to wait
to process one transaction at a time. In addition, you can facilitate payments,
the application allows multiple payment methods.</p>
<p>The POS application is so simple and accessible to use that your shop or
restaurant will never need any other tool to manage orders. Due to its smart
and user-friendly interface you don't need any training to learn how to use it.
Think of it as an out-of-the-box solution to boost your business' productivity.
</p>
]]>
</field>
</record>
<record id="blog_post_4" model="blog.post">
<field name="name">Announcing a New Partnership</field>
<field name="blog_id" ref="blog_blog_1"/>
<field name="tag_ids" eval="[(6, 0, [ref('blog_tag_1')])]"/>
<field name="website_published" eval="True"/>
<field name="website_meta_keywords">OpenERP, Partnership, News, Accounting</field>
<field name="website_meta_description">Our company partners with OpenERP to develop accounting best practices.</field>
<field name="content"><![CDATA[
<section data-snippet-id='image-text'>
<div class="container">
<div class="row">
<div class="col-md-6 mt16 mb16">
<img class="img-responsive shadow" src="/website/static/src/img/text_image.png"/>
</div>
<div class="col-md-6 mt16">
<p>
We are proud to announce a new partnership with
the company OpenERP. Their open source application suite
will allow us to reach new markets, specifically in
the accounting area.
</p><p>
The full integration with the company inventory
and accounting, will give our customers real time statistics
without the hassle of integrating several applications.
</p>
</div>
</div>
<field name="tag_ids" eval="[(6, 0, [ref('blog_tag_1')])]"/>
<field name="content_image">/website_blog/static/src/img/post2.jpg</field>
<field name="content">
<![CDATA[<section class="row readable">
<div class="col-md-12 mb32">
<img class="img-responsive" src="/website_blog/static/src/img/CMS_WMS_screens.jpg"/>
</div>
<div class="col-md-6 col-md-offset-3 mb16 mt16">
<p class="text-center">
New Features Launched
</p>
<p class="text-center">
To add to an already comprehensive set of OpenERP
features, a website content management system (CMS
or WMS) has been developed and a beta release is
available from today, 31st January 2014.
</p>
</div>
</section>
<section class="mt16 mb16" data-snippet-id='text-block'>
<div class="container">
<div class="row">
<div class="col-md-12 text-center mt16 mb32">
<h2>
OpenERP Project Management
</h2>
<h3 class="text-muted">Infinitely flexible. Incredibly easy to use.</h3>
</div>
<div class="col-md-12 mb16 mt16">
<p>
OpenERP's <b>collaborative and realtime</b> project
management helps your team get work done. Keep
track of everything, from the big picture to the
minute details, from the customer contract to the
billing.
</p><p>
Organize projects around <b>your own processes</b>. Work
on tasks and issues using the kanban view, schedule
tasks using the gantt chart and control deadlines
in the calendar view. Every project may have it's
own stages allowing teams to optimize their job.
</p>
</div>
</div>
</div>
<section class="readable">
<p>
OpenERP claims to be 'the Open Source software that makes
building your company's website and selling your products
online easy'. So how true is this statement?
</p><p>
"OpenERP's latest launch will allow a business to go from
zero to trading online quicker than ever before,” Stuart
Mackintosh, MD of Open Source specialist and OpenERP
integration partner, OpusVL, explains. “The investment
required to have a fully automated business system is
dramatically reduced, enabling the small and medium
enterprise to compete at a level of functionality and
performance previously reserved for the big IT investors."
</p>
<blockquote>
<p>
"Finally, the leading edge is being brought to the masses.
It will now be the turn of the big players to catch up to
the superior technologies of the SME."
</p>
</blockquote>
<p>
"This is another clever and highly disruptive move by
OpenERP,which will force other technology providers to
take another look at the value they are providing to ensure
that their 'solutions' can still compete."
</p><p>
"OpenERP now competes on many fronts, with no real
competition out there to knock them off the top spot.
With the launch of their integrated CMS and Ecommerce
systems,it only elevates their position as one of the leading
lights in the open source revolution. It will be at least 5
years before another ERP or CMS provider will be able to
compete at this level due to the technology currently
employed by most industry providers."
</p>
<h4>Adding to industry leading technology</h4>
<p>
Like many modern website editors, with OpenERP you can edit
content in-line, enabling you to see exactly what you are
changing and ensure your changes suit the context.
</p><p>
However, unlike other web content management systems, it
fully integrates into the back-end database. This means
that when you edit a product description, image or price,
it updates the product database in real time, providing a
true self-service window into the business.
</p><p>
This provides a single source of data for your company and
removes the need to create offline synchronisation between
website and product database.
</p><p>
As it comes, there is a default website based on Bootstrap
3, the latest industry standard for rapid development of
multi-device websites backed by Twitter, so can be directly
integrated with many web tools and works across all devices
by default.
</p>
<h4>So, what does this mean to me and my business?</h4>
<p>
The CMS removes the need for Magento integration for the
shopping basket and Drupal/Joomla for the website. For any
organisation, this will reduce the technology footprint and
eliminate the complexities of FTP or file transfer data
uploads and exports which for many, are manual tasks.
Implementation is easier and the web designer can get
straight on with developing the site without requiring the
project management and interactions with site developers,
providing a quicker and more efficient deployment. However,
for larger sites, stringent process and project management
disciplines are still required to ensure a low-risk project.
</p>
<h4>How does it work in practice?</h4>
<p>
When items are placed in the basket, a sales order is
created automatically to reflect the basket contents.
Payments are recorded on the balance sheet and all
accounting journal entries are automatic. As it is in real
time, stock records are always accurate and decremented on
the fly when orders placed.
</p><p>
Automatic translations can be created for international
traders and available languages selected.
</p>
<p>
Customer queries and returns can be set up to use the case
handling system which will escalate depending on customer
spend, grouping or profile and notify relevant parties as
appropriate.
</p><p>
More information about the feature set can be found
<a href="https://www.openerp.com/website_cms" target="_TOP">
on the OpenERP website here</a>
</p>
<h4>Created in just four months</h4>
<p>
OpenERP competently manages customer and product data, and
has mature sales work-flow built in, so the addition of the
E-commerce module was achieved by presenting these
components through a customer-friendly interface so most
of the effort invested was creating the CMS functions. This
was achieved within just four months of development by a
core team of 6 OpenERP developers and significant community
support.
</p><p>
Inspiration has come from various other platforms including
Prestashop, Magento and Drupal and contributors bring many
years of industry experience across many platforms.
</p>
</section>
]]>
</field>
</record>
<record id="blog_post_3" model="blog.post">
<field name="name">Sorry SAP Campaign - The Making Of</field>
<field name="sub_title">To lead the enterprise management market with a fully open source software.</field>
<field name="blog_id" ref="blog_blog_1"/>
<field name="website_published" eval="True"/>
<field name="website_meta_keywords">OpenERP, News, Sorry SAP</field>
<field name="website_meta_description">Sorry SAP Campaign - The Making Of</field>
<field name="content_image">/website_blog/static/src/img/post3.jpg</field>
<field name="content"><![CDATA[
<section class="readable">
<p>I needed to change the world. I wanted to ... You know how
it is when you are young; you have big dreams, a lot of energ
and naïve stupidity. My dream was to lead the enterprise
management market with a fully open source software.(I also
wanted to get 100 employees before 30 years old with a
self-financed company but I failed this one by a few months).
</p>
</section>
<section class="readable">
<p>
To fuel my motivation, I had to pick someone to fight
against. In business, it's like a playground. When you
arrive in a new school, if you want to quickly become the
leader, you must choose the class bully, the older guy who
terrorises small boys,and kick his butt in front of
everyone. That was my strategy with SAP, the enterprise
software giant.
</p><p>
So, in 2005, I started to develop the TinyERP product, the
software that (at least in my mind) would change the enterprise
world. While preparing for the "day of the fight" in 2006,
I <a href="http://whois.domaintools.com/sorrysap.com">
bought the SorrySAP.com </a>domain name. I put it on hold
for 6 years, waiting for the right moment to use it.
I thought it would take 3 years to deprecate a 77 billion
dollars company just because open source is so cool.
Sometimes it's better for your self-motivation not to
face reality...
</p><p>
To make things happen, I worked hard, very hard. I worked
13 hours a day, 7 days a week, with no vacations for 7
years.I lost friendships and broke up with my girlfriend in
the process (fortunately, I found a more valuable wife
now. I will explain later why she is worth 1 million EUR
:).
</p><p>
Three years later, I discovered you can't change the world
if you are "tiny". Especially if the United States is part
of this world, where it's better to be a BigERP, rather
than a TinyERP. Can you imagine how small you feel
<a href="http://www.slideshare.net/openobject/danone-deployes-openerp-locally">
in front of Danone's directors</a> asking; "but why
should we pay millions of dollars for a tiny software?"
So, we renamed TinyERP to OpenERP.
</p><p>
As we worked hard, things started to evolve. We were
developing dozens of modules for OpenERP, the open source
community was growing and I was even able to pay all
employees' salaries at the end of the month without fear
(which was a situation I struggled with for 4 years).
</p><p>
In 2010, we had a 100+ employees company selling services
on OpenERP and a powerful but ugly product. This is what
happens when delivering services to customers distracts
you from building an exceptional product.
</p><p>
It was time to do a pivot in the business model.
</p>
<h3>The Pivot</h3>
<p>
We wanted to switch from a service company to a software
publisher company. This would allow to increase our efforts
in our research and development activities. As a result,
we changed our
business model and decided to stop our services to
customers and focus on building a strong partner network
and maintenance offer. This would cost money, so I had to
raise a few million euros.
</p><p>
After a few months of pitching investors, I got roughly
10 LOI from different VCs. We chosed Sofinnova Partners,
the biggest European VC, and Xavier Niel the founder of
Iliad, the only company in France funded in the past 10
years to have reached the 1 billion euro valuation.
</p><p>
I signed the LOI. I didn't realize that this contract could
have turned me into a homeless person. (I already had a dog,
all I needed was to lose a lot of money to become homeless).
The fund raising was based on a company valuation but there
was a financial mechanism to re-evaluate the company up by
9.8 m€ depending on the turnover of the next 4 years. I should
have received warrants convertible into shares if we achieved
the turnover targeted in the business plan.
</p><p>
The night before receiving the warrants in front of the
notary, my wife checked the contracts. She asked me what
would be the taxation on these warrants. I rang the lawyer
and guess what? Belgium is probably the only country in
the world where you have to pay taxes on warrants when you
receive them, even if you never reach the conditions to
convert them into shares.If I had accepted these warrants,
I would have had to pay a 12.5% tax on 9.8 m€; resulting
in a tax of 1.2m€ to pay in 18 months! So, my wife is worth
1.2 million EUR. I would have ended up a homeless person
without her, as I still did not have a salary at that time.
</p><p>
We changed the deal and I got the 3 million EUR. It allowed
me to recruit a rocking management team.
</p>
<img class="img-responsive" src="/website_blog/static/src/img/OpemERP_board.jpg"/>
<h3 class="mt16">Being a mature company<h3>
<p>
With this money in our bank account, we boosted two
departments: R&D and Sales. We burned two million EUR in
18 months,mostly in salaries. The company started to grow
even faster.We developed a partner network of 500 partners
in 100 countries and we started to sign contracts with 6
zeros.
</p><p>
Then, things became different. You know, tedious things like
handling human resources, board meetings, dealing with big
customer contracts, traveling to launch international
subsidiaries. We did boring stuff like budgets, career paths,
management meetings, etc.
</p><p>
2011 was a complex year. We did not meet our expectations:
we only achieved 70% of the forecasted sales budget. Our
management meetings were tense. We under performed. We were not
satisfied with ourselves. We had a constant feeling that we
missed something. It's a strange feeling to build extraordinary
things but to not be proud of ourselves.
</p><p>
But one day, someone (I don't remember who, I have a
goldfish memory) made a graph of the monthly turnover
of the past 2 years. It was like waking up from a nighmare.
In fact,it was not that bad, we had multiplied by 10 the
monthly turnover over the span of roughly two years!
This is when we understood that OpenERP is a marathon,
not a sprint. Only 100% growth a year is ok... if you can
keep the rhythm for several years.
</p>
<img class="img-responsive" src="/website_blog/static/src/img/turnover_updated.png"/>
<p class="text-center" section_inner="1">
OpenERP Monthly Turnover
</p><p>
As usual, I should have listened to my wife. She is way
more lucid than I am. Every week I complained to her "it's
not good enough, we should grow faster, what am I missing?"
and she used to reply; "But you already are the
fastest growing company in Belgium!". (Deloitte awarded
us as the fastest growing company of Belgium with 1549%
growth of the turnover between 2007 and 2011)
</p>
<h3 class="mt16">Changing the world</h3>
<p>
Then, the dream started to become reality. We started to
get clues that what we did would change the world:
</p>
<ul>
<li>
With 1.000 installations per day, we became the most
installed management software in the world,
</li><li>
<a href="http://www.amazon.com/OpenERP-Evaluation-SAP-as-Reference/dp/296008764X/ref=sr_1_3?ie=UTF8&qid=1351150366&sr=8-3&keywords=openerp">
Analysts from Big 4 started to prefer OpenERP over SAP,
</a>
</li><li>
OpenERP is now a <a href="http://www.nathan.fr/catalogue/catalogue_detail_enseignants.asp?ean13=9782091619262">
compulsory subject for the baccalaureate in France</a>
like Word, Excel and Powerpoint
</li><li>
60 new modules are released every month (we became
the wikipedia of the management software thanks to
our strong community)
</li>
</ul>
<p>
Something is happening... And it's big!
</p><p>
OpenERP 7.0 is about to be released and I know you will be
astonished by it.
</p><p>
The official release is planned for the 21th of December.
As the Mayas predicted it, this is the end of an age,
the old ERP dinosaurs.
</p><p>
It's time to pull out the Ace: the SorrySAP.com domain
name that I bought 6 years ago.
</p>
</section>
]]>
</field>
</record>
</data>
</openerp>
+20
View File
@@ -0,0 +1,20 @@
_blog_blog:
blog.blog
=========
In ``blog.blog``, added field ``subtitle`` which Indicates the subtitle of blogs.
- ``subtitle``: fields.char('Blog Subtitle')
mail.message
============
In ``mail.message``, added field ``discussion`` which Indicates the unique identification
of paragraph on blog post.
- ``discussion``: fields.char('Discussion Unique Name')
blog.post
=========
Fields
++++++
- ``sub_title`` : contains the subtitle of every blog post.
- ``visits`` : Indicates the number of visits on evry blog post.
- ``ranking`` : Indicates the ranking on every blog post.
+26
View File
@@ -7,3 +7,29 @@ Changelog
----------------
- created ``website_blog`` menu, build on defunct document_page module.
- added new feature ``Inline Discussion`` , that will allow a user to comment
on every paragraph on blog post
- added new feature ``Select to Tweet``, that will alllow a user tweet a selected
text from blog to post , directly on twitter.
WebsiteBlog(controller)
=======================
Methods
+++++++
- ``blog`` : remove routing related to date.
- ``blog_post`` : updated with , suggestion of next post to the user based on
cookie and number of views.
- ``discussion`` : added method , contains a detail of discussion on every paragraph,
if count is true it only return len of ids else return full detail.
def discussion(self, post_id=0, discussion=None, count=False, **post)
- ``post_discussion`` : added methodt, that allow to post discussion on any paragraph.
def post_discussion(self, blog_post_id=0, **post)
- ``change_bg`` : added method allow a user to change background image on blog
post from front-end.
def change_bg(self, post_id=0, image=None, **post)
- ``get_user`` : added method , that will return True if user is public else False.
def get_user(self, **post):
return [False if request.session.uid else True]
+21
View File
@@ -0,0 +1,21 @@
.. _controller:
WebsiteBlog(controller)
=======================
Methods
+++++++
- ``blog`` : remove routing related to date.
- ``blog_post`` : updated with , suggestion of next post to the user based on
cookie and number of views.
- ``discussion`` : added method , contains a detail of discussion on every paragraph,
if count is true it only return len of ids else return full detail.
def discussion(self, post_id=0, discussion=None, count=False, **post)
- ``post_discussion`` : added methodt, that allow to post discussion on any paragraph.
def post_discussion(self, blog_post_id=0, **post)
- ``change_bg`` : added method allow a user to change background image on blog
post from front-end.
def change_bg(self, post_id=0, image=None, **post)
- ``get_user`` : added method , that will return True if user is public else False.
def get_user(self, **post):
return [False if request.session.uid else True]
+24 -58
View File
@@ -19,28 +19,23 @@
#
##############################################################################
import random
import difflib
from datetime import datetime
from openerp import tools
from openerp import SUPERUSER_ID
from openerp.osv import osv, fields
from openerp.tools.translate import _
import difflib
class Blog(osv.Model):
_name = 'blog.blog'
_description = 'Blogs'
_inherit = ['mail.thread', 'website.seo.metadata']
_order = 'name'
_columns = {
'name': fields.char('Name', required=True),
'name': fields.char('Blog Name', required=True),
'subtitle': fields.char('Blog Subtitle'),
'description': fields.text('Description'),
'blog_post_ids': fields.one2many(
'blog.post', 'blog_id',
'Blogs',
),
}
@@ -49,49 +44,32 @@ class BlogTag(osv.Model):
_description = 'Blog Tag'
_inherit = ['website.seo.metadata']
_order = 'name'
_columns = {
'name': fields.char('Name', required=True),
'blog_post_ids': fields.many2many(
'blog.post', string='Posts',
),
}
class MailMessage(osv.Model):
_inherit = 'mail.message'
_columns = {
'discussion': fields.char('Discussion Unique Name'),
}
class BlogPost(osv.Model):
_name = "blog.post"
_description = "Blog Post"
_inherit = ['mail.thread', 'website.seo.metadata']
_order = 'write_date DESC'
# maximum number of characters to display in summary
_shorten_max_char = 250
_order = 'id DESC'
def get_shortened_content(self, cr, uid, ids, name, arg, context=None):
def _compute_ranking(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,
expand_options={
'oe_expand_container_tag': 'div',
'oe_expand_container_class': 'oe_mail_expand text-center',
'oe_expand_container_content': '',
'oe_expand_a_href': '/blogpost/%d' % page.id,
'oe_expand_a_class': 'oe_mail_expand btn btn-info',
'oe_expand_separator_node': 'br',
},
protect_sections=True,
)
except Exception:
body_short = False
res[page.id] = body_short
for blog_post in self.browse(cr, uid, ids, context=context):
d = datetime.now() - datetime.strptime(blog_post.create_date, tools.DEFAULT_SERVER_DATETIME_FORMAT)
res[blog_post.id] = blog_post.visits * (0.5+random.random()) / max(3, d.days)
return res
_columns = {
'name': fields.char('Title', required=True, translate=True),
'sub_title' : fields.char('Sub Title', translate=True),
'content_image': fields.binary('Background Image'),
'blog_id': fields.many2one(
'blog.blog', 'Blog',
@@ -101,32 +79,22 @@ class BlogPost(osv.Model):
'blog.tag', string='Tags',
),
'content': fields.html('Content', translate=True),
'shortened_content': fields.function(
get_shortened_content,
type='html',
string='Shortened Content',
help="Shortened content of the page that serves as a summary"
),
# website control
'website_published': fields.boolean(
'Publish', help="Publish on the website"
),
'website_published_datetime': fields.datetime(
'Publish Date'
),
# TDE TODO FIXME: when website_mail/mail_thread.py inheritance work -> this field won't be necessary
'website_message_ids': fields.one2many(
'mail.message', 'res_id',
domain=lambda self: [
'&', ('model', '=', self._name), ('type', '=', 'comment')
'&', '&', ('model', '=', self._name), ('type', '=', 'comment') , ('discussion', '=', False)
],
string='Website Messages',
help="Website communication history",
),
# technical stuff: history, menu (to keep ?)
'history_ids': fields.one2many(
'blog.post.history', 'post_id',
'History', help='Last post modifications'
'History', help='Last post modifications',
deprecated= 'Will be removed in v9.'
),
# creation / update stuff
'create_date': fields.datetime(
@@ -145,9 +113,13 @@ class BlogPost(osv.Model):
'res.users', 'Last Contributor',
select=True, readonly=True,
),
'visits': fields.integer('No of Views', readonly=True),
'ranking': fields.function(_compute_ranking, string='Ranking', type='float'),
}
_defaults = {
'website_published': False
'website_published': False,
'visits': 0,
'ranking': 0
}
def create_history(self, cr, uid, ids, vals, context=None):
@@ -183,11 +155,6 @@ class BlogPost(osv.Model):
})
return super(BlogPost, self).copy(cr, uid, id, default=default, context=context)
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)
class BlogPostHistory(osv.Model):
_name = "blog.post.history"
_description = "Blog Post History"
@@ -216,4 +183,3 @@ class BlogPostHistory(osv.Model):
diff = difflib.HtmlDiff()
return diff.make_table(line1, line2, "Revision-%s" % (v1), "Revision-%s" % (v2), context=True)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -9,5 +9,15 @@
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
</record>
<!-- over write record rule to allow to see partner detail to anonymous user -->
<record model="ir.rule" id="base.res_partner_portal_public_rule">
<field name="name">res_partner: portal/public: read access on my commercial partner</field>
<field name="model_id" ref="base.model_res_partner"/>
<field name="domain_force">[]</field>
<field name="groups" eval="[(4, ref('base.group_portal')), (4, ref('base.group_public'))]"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
<field name="perm_write" eval="False"/>
</record>
</data>
</openerp>
@@ -0,0 +1,63 @@
(function(){
$.fn.share = function(options) {
var option = $.extend($.fn.share.defaults,options);
$.extend($.fn.share,{
init : function(shareable) {
var self = this;
$.fn.share.defaults.shareable = shareable;
$.fn.share.defaults.shareable.on('mouseup',function(){
self.popOver();
});
$.fn.share.defaults.shareable.on('mousedown',function(){
self.destroy();
});
},
getContent : function() {
var current_url = window.location.href
var selected_text = this.getSelection('string').substring(0,option.maxLength-(current_url.length+option.author_name.length+7));
var text = encodeURIComponent('\"'+selected_text+'\" '+'--@'+option.author_name+' '+current_url)
return '<a onclick="window.open(\''+option.shareLink+text+'\',\'_'+option.target+'\',\'location=yes,height=570,width=520,scrollbars=yes,status=yes\')"><i class="fa fa-twitter fa-lg"/></a>';
},
getSelection : function(share) {
if(window.getSelection){
return (share=='string')?String(window.getSelection().getRangeAt(0)).replace(/\s{2,}/g, ' '):window.getSelection().getRangeAt(0);
}
else if(document.selection){
return (share=='string')?document.selection.createRange().text.replace(/\s{2,}/g, ' '):document.selection.createRange();
}
},
popOver : function() {
this.destroy();
if(this.getSelection('string').length < option.minLength)
return;
var data = this.getContent();
var range = this.getSelection();
var newNode = document.createElement("mark");
range.surroundContents(newNode);
$('mark').addClass(option.className);
$('.'+option.className).popover({trigger:'manual', placement: option.placement, html: true
, content:function(){
return data;
}
});
$('.'+option.className).popover('show');
},
destroy : function(){
$('.'+option.className).popover('hide');
$('mark').contents().unwrap();
$('mark').remove();
}
});
$.fn.share.init(this);
};
$.fn.share.defaults = {
shareLink : "http://twitter.com/intent/tweet?text=",
minLength : 5,
maxLength : 140,
target : "blank",
className : "share",
placement : "top",
};
}());
@@ -9,6 +9,12 @@
display: block;
}
.read_width {
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.blog_content a.oe_mail_expand:after {
content: " →";
}
@@ -20,3 +26,127 @@ p.post-meta {
position: relative;
top: -5px;
}
div#blog_angle_down a:hover {
text-decoration: none;
}
.cover {
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-color: black;
color: white;
position: relative;
}
.cover .blog_title {
position: absolute;
text-align: center;
top: 20%;
left: 0;
right: 0;
}
.cover .blog_title h1 {
font-weight: bold;
}
.cover_footer {
min-height: 350px;
height: 65vh;
cursor: pointer;
}
/*Inline Discussion */
.discussion {
padding: 5px 10px 10px;
position: absolute;
top: 0;
left: 0;
line-height: 16px;
font-size: 13px;
font-weight: bold;
font-family: sans-serif;
text-align: center;
z-index: 7;
}
.discussion > a {
opacity: 0;
display: block;
overflow: hidden;
width: 20px;
height: 17px;
color: white;
text-decoration: none;
cursor: pointer;
background: #bbbbbb;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
-ms-border-radius: 2px;
-o-border-radius: 2px;
border-radius: 2px;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
-o-transition: all 0.5s;
transition: all 0.5s;
}
.discussion > a.has-comments {
opacity: 0.6;
}
.discussion-contain:hover .discussion > a {
opacity: 1;
}
.discussion > a:after {
border-right: 7px solid transparent;
border-top: 7px solid #bbbbbb;
right: 19px;
top: 22px;
height: 0;
width: 0;
display: block;
content: " ";
position: absolute;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
-o-transition: all 0.5s;
transition: all 0.5s;
}
.discussion:hover > a, .discussion.hovered > a {
opacity: 1;
background: #57ad68;
}
.discussion:hover > a:after, .discussion.hovered > a:after {
border-top-color: #57ad68;
}
#discussions_wrapper {
position: absolute;
top: 0;
left: 0;
}
#discussions_overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 8;
display: none;
}
.discussion .popover-content {
max-height: 250px;
width: 250px;
overflow: auto;
font-weight: normal;
}
mark + .popover {
cursor: pointer;
}
@@ -1,5 +1,4 @@
@charset "utf-8"
@import "compass/css3"
.css_website_mail
@@ -10,6 +9,11 @@
&:first-of-type
display: block
.read_width
max-width: 700px
margin-left: auto
margin-right: auto
.blog_content
a.oe_mail_expand:after
content: " →"
@@ -20,3 +24,113 @@ p.post-meta
position: relative
top: -5px
div#blog_angle_down
a:hover
text-decoration: none
.cover
-webkit-background-size: cover
-moz-background-size: cover
-o-background-size: cover
background-size: cover
background-position: center
background-repeat: no-repeat
background-color: #000
color: #fff
position: relative
.blog_title
position: absolute
text-align: center
top: 20%
left: 0
right: 0
h1
font-weight: bold
.cover_footer
min-height : 350px
height: 65vh
cursor: pointer
/*Inline Discussion
.discussion
padding: 5px 10px 10px
position: absolute
top: 0
left: 0
line-height: 16px
font-size: 13px
font-weight: bold
font-family: sans-serif
text-align: center
z-index: 7
> a
opacity: 0
display: block
overflow: hidden
width: 20px
height: 17px
color: white
text-decoration: none
cursor: pointer
background: #bbbbbb
-webkit-border-radius: 2px
-moz-border-radius: 2px
-ms-border-radius: 2px
-o-border-radius: 2px
border-radius: 2px
-webkit-transition: all 0.5s
-moz-transition: all 0.5s
-o-transition: all 0.5s
transition: all 0.5s
&.has-comments
opacity: .6
.discussion-contain:hover .discussion > a
opacity: 1
.discussion
> a:after
border-right: 7px solid transparent
border-top: 7px solid #bbbbbb
right: 19px
top: 22px
height: 0
width: 0
display: block
content: " "
position: absolute
-webkit-transition: all 0.5s
-moz-transition: all 0.5s
-o-transition: all 0.5s
transition: all 0.5s
&:hover > a, &.hovered > a
opacity: 1
background: #57AD68
&:hover > a:after, &.hovered > a:after
border-top-color: #57AD68
#discussions_wrapper
position: absolute
top: 0
left: 0
#discussions_overlay
position: fixed
top: 0
left: 0
right: 0
bottom: 0
background: rgba(0, 0, 0, 0.5)
z-index: 8
display: none
.discussion .popover-content
max-height: 250px
width: 250px
overflow: auto
font-weight: normal
mark + .popover
cursor: pointer
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

@@ -27,7 +27,38 @@
}).then(function (cat_id) {
document.location = '/blogpost/new?blog_id=' + cat_id;
});
}
},
}),
edit: function () {
$('.popover').remove();
this._super();
var vHeight = $(window).height();
$('body').on('click','#change_cover',_.bind(this.change_bg,{},vHeight));
$('body').on('click', '#clear_cover',_.bind(this.clean_bg,{},vHeight));
},
save : function() {
var res = this._super();
if ($('.cover').length){
openerp.jsonRpc("/blogpsot/change_background", 'call', {
'post_id' : $('#blog_post_name').attr('data-oe-id'),
'image' : $('.cover').css('background-image').replace(/url\(|\)|"|'/g,''),
});
}
return res;
},
clean_bg : function(vHeight) {
$('.js_fullheight').css({"background-image":'none', 'min-height': vHeight});
},
change_bg : function(vHeight) {
var self = this;
var editor = new website.editor.ImageDialog();
editor.on('start', self, function (o) {
o.url = $('.js_fullheight').length ? $('.js_fullheight').css('background-image').replace(/url\(|\)|"|'/g,'') : '';
});
editor.on('save', self, function (o) {
$('.js_fullheight').css({"background-image": o.url && o.url !== "" ? 'url(' + o.url + ')' : "", 'min-height': vHeight})
});
editor.appendTo('body');
},
});
})();
@@ -0,0 +1,207 @@
// Inspired from https://github.com/tsi/inlineDisqussions
(function () {
'use strict';
var website = openerp.website,
qweb = openerp.qweb;
website.add_template_file('/website_blog/static/src/xml/website_blog.inline.discussion.xml');
website.blog_discussion = openerp.Class.extend({
init: function(options) {
var self = this ;
self.discus_identifier;
var defaults = {
identifier: 'name',
position: 'right',
post_id: $('#blog_post_name').attr('data-blog-id'),
content : false,
public_user: false,
};
self.settings = $.extend({}, defaults, options);
self.do_render(self);
},
do_render: function(data) {
var self = this;
if ($('#discussions_wrapper').length === 0 && self.settings.content.length > 0) {
$('<div id="discussions_wrapper"></div>').appendTo($('#blog_content'));
}
// Attach a discussion to each paragraph.
$(self.settings.content).each(function(i) {
self.discussion_handler(i, $(this));
});
// Hide the discussion.
$('html').click(function(event) {
if($(event.target).parents('#discussions_wrapper, .main-discussion-link-wrp').length === 0) {
self.hide_discussion();
}
if(!$(event.target).hasClass('discussion-link') && !$(event.target).parents('.popover').length){
if($('.move_discuss').length){
$('.js_discuss').next().removeClass('move_discuss');
$('.js_discuss').next().animate({
'marginLeft': "+=40%"
});
$('#discussions_wrapper').animate({
'marginLeft': "+=250px"
});
}
}
});
},
prepare_data : function(identifier,comment_count) {
var self = this;
return openerp.jsonRpc("/blogpost/get_discussion/", 'call', {
'post_id': self.settings.post_id,
'discussion':identifier,
'count' : comment_count, //if true only get length of total comment, display on discussion thread.
})
},
discussion_handler : function(i, node) {
var self = this;
var identifier;
// You can force a specific identifier by adding an attribute to the paragraph.
if (node.attr('data-discus-identifier')) {
identifier = node.attr('data-discus-identifier');
}
else {
while ($('[data-discus-identifier="' + self.settings.identifier + '-' + i + '"]').length > 0) {
i++;
}
identifier = self.settings.identifier + '-' + i;
}
self.prepare_data(identifier,true).then(function(data){
self.prepare_discuss_link(data,identifier,node)
});
},
prepare_discuss_link : function(data, identifier, node) {
var self = this;
var cls = data > 0 ? 'discussion-link has-comments' : 'discussion-link';
var a = $('<a class="'+ cls +' css_editable_mode_hidden" />')
.attr('data-discus-identifier', identifier)
.attr('data-discus-position', self.settings.position)
.text(data > 0 ? data : '+')
.attr('data-contentwrapper','.mycontent')
.wrap('<div class="discussion" />')
.parent()
.appendTo('#discussions_wrapper');
a.css({
'top': node.offset().top,
'left': self.settings.position == 'right' ? node.outerWidth() + node.offset().left: node.offset().left - a.outerWidth()
});
node.attr('data-discus-identifier', identifier).mouseover(function() {
a.addClass("hovered");
}).mouseout(function() {
a.removeClass("hovered");
});
a.delegate('a.discussion-link', "click", function(e) {
e.preventDefault();
if(!$('.move_discuss').length){
$('.js_discuss').next().addClass('move_discuss');
$('.js_discuss').next().animate({
'marginLeft': "-=40%"
});
$('#discussions_wrapper').animate({
'marginLeft': "-=250px"
});
}
if ($(this).is('.active')) {
e.stopPropagation();
self.hide_discussion();
}
else {
self.get_discussion($(this), function(source) {});
}
});
},
get_discussion : function(source, callback) {
var self = this;
var identifier = source.attr('data-discus-identifier');
self.hide_discussion();
self.discus_identifier = identifier;
var elt = $('a[data-discus-identifier="'+identifier+'"]');
elt.append(qweb.render("website.blog_discussion.popover", {'identifier': identifier , 'options': self.settings}));
var comment = '';
self.prepare_data(identifier,false).then(function(data){
_.each(data, function(res){
comment += qweb.render("website.blog_discussion.comment", {'res': res});
});
$('.discussion_history').html('<ul class="media-list">'+comment+'</ul>');
self.create_popover(elt, identifier);
// Add 'active' class.
$('a.discussion-link, a.main-discussion-link').removeClass('active').filter(source).addClass('active');
elt.popover('hide').filter(source).popover('show');
callback(source);
});
},
create_popover : function(elt, identifier) {
var self = this;
elt.popover({
placement:'right',
trigger:'manual',
html:true, content:function(){
return $($(this).data('contentwrapper')).html();
}
}).parent().delegate(self).on('click','button#comment_post',function(e) {
e.stopImmediatePropagation();
self.post_discussion(identifier);
});
},
validate : function(public_user){
var comment = $(".popover textarea#inline_comment").val();
if (public_user){
var author_name = $('.popover input#author_name').val();
var author_email = $('.popover input#author_email').val();
if(!comment || !author_name || !author_email){
if (!author_name)
$('div#author_name').addClass('has-error');
else
$('div#author_name').removeClass('has-error');
if (!author_email)
$('div#author_email').addClass('has-error');
else
$('div#author_email').removeClass('has-error');
if(!comment)
$('div#inline_comment').addClass('has-error');
else
$('div#inline_comment').removeClass('has-error');
return false
}
}
else if(!comment) {
$('div#inline_comment').addClass('has-error');
return false
}
$("div#inline_comment").removeClass('has-error');
$('div#author_name').removeClass('has-error');
$('div#author_email').removeClass('has-error');
$(".popover textarea#inline_comment").val('');
$('.popover input#author_name').val('');
$('.popover input#author_email').val('');
return [comment, author_name, author_email]
},
post_discussion : function(identifier) {
var self = this;
var val = self.validate(self.settings.public_user)
if(!val) return
openerp.jsonRpc("/blogpost/post_discussion", 'call', {
'blog_post_id': self.settings.post_id,
'discussion': self.discus_identifier,
'comment': val[0],
'name' : val[1],
'email': val[2],
}).then(function(res){
$(".popover ul.media-list").prepend(qweb.render("website.blog_discussion.comment", {'res': res[0]}))
var ele = $('a[data-discus-identifier="'+ self.discus_identifier +'"]');
ele.text(_.isNaN(parseInt(ele.text())) ? 1 : parseInt(ele.text())+1)
ele.addClass('has-comments');
});
},
hide_discussion : function() {
var self = this;
$('a[data-discus-identifier="'+ self.discus_identifier+'"]').popover('destroy');
$('a.discussion-link').removeClass('active');
}
});
})();
@@ -0,0 +1,40 @@
$(document).ready(function() {
function page_transist(event) {
event.preventDefault();
newLocation = $('.js_next')[0].href;
var top = $('.cover_footer').offset().top;
$('.cover_footer').animate({
height: $(window).height()+'px'
}, 300);
$('html, body').animate({
scrollTop: top
}, 300, 'swing', function() {
window.location.href = newLocation;
});
}
function animate(event) {
event.preventDefault();
event.stopImmediatePropagation();
var target = $(this.hash);
$('html, body').stop().animate({
'scrollTop': target.offset().top - 32
}, 500, 'swing', function () {
window.location.hash = 'blog_content';
});
}
var content = $(".js_discuss").next().find('p');
if(content){
openerp.jsonRpc("/blog/get_user/", 'call', {}).then(function(data){
$('#discussions_wrapper').empty();
new openerp.website.blog_discussion({'content' : content, 'public_user':data[0]});
});
}
$('.js_fullheight').css('min-height', $(window).height());
$(".js_tweet").share({'author_name':$('#blog_author').text()});
$('.cover_footer').on('click',page_transist);
$('a[href^="#blog_content"]').on('click', animate);
});
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="website.blog_discussion.comment">
<li class="media">
<div class="pull-left">
<img class="media-object img-circle" t-att-src="res.author_image" style="width: 30px;"/>
</div>
<div t-attf-class="pull-right btn-group js_publish_management #{res.website_published and 'css_published' or 'css_unpublished'} #{res.publish ? '' : 'hidden'}" data-object="mail.message" t-att-data-id="res.id">
<button class="btn btn-danger btn-xs js_publish_btn">Not Published</button>
<button class="btn btn-success btn-xs js_publish_btn">Published</button>
</div>
<div class="media-body">
<div t-esc='res.body'/>
<small class="text-muted">
by
<span t-esc='res.author_name'/>
</small>
</div>
</li>
</t>
<t t-name="website.blog_discussion.popover">
<div class="mycontent hidden">
<input name="discussion" t-att-value="identifier" type="hidden"/>
<input name="blog_post_id" t-att-value="options.post_id" type="hidden"/>
<div id="inline_comment">
<textarea class="mb8 form-control" rows="2" id="inline_comment" placeholder="Write a comment..."/>
</div>
<div id="author_name">
<input id="author_name" name="user_name" t-attf-class="form-control #{options.public_user ? '' : 'hidden'}" placeholder="Your name..."/>
</div>
<div id="author_email">
<input id="author_email" name="user_email" t-attf-class="mt8 mb8 form-control #{options.public_user ? '' : 'hidden'}" placeholder="Your Email..."/>
</div>
<button id='comment_post' class="btn btn-primary btn-xs mb8">Post</button>
<div class="discussion_history"/>
</div>
</t>
</templates>
@@ -21,21 +21,17 @@
<t t-call="website.layout">
<div id="wrap">
<div class="oe_structure"/>
<section groups="base.group_website_publisher">
<div class="container text-center mt16">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&amp;times;</button>
<p>
This page is great to improve your <strong>Search Engine Optimization</strong>;
You can review titles, keywords and descriptions of all blogs at once.
</p><p>
You should <strong>add a banner on the top</strong> as it is a frequent landing page for new visitors.
<span class="text-muted">This box will not be visible to your visitors.</span>
</p>
</div>
</div>
</section>
<section class="container">
<div class="alert alert-warning alert-dismissable mt16" groups="base.group_website_publisher">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&amp;times;</button>
<p>
This page is great to improve your <strong>Search Engine Optimization</strong>;
You can review titles, keywords and descriptions of all blogs at once.
</p><p>
You should <strong>add a banner on the top</strong> as it is a frequent landing page for new visitors.
<span class="text-muted">This box will not be visible to your visitors.</span>
</p>
</div>
<t t-call="website.pager" >
<t t-set="classname">pull-right</t>
</t>
@@ -95,47 +91,71 @@
<!-- Blog Post Summary -->
<template id="blog_post_short" name="Blog Post Summary">
<template id="blog_post_short" name="Blog Posts">
<t t-call="website_blog.index">
<div t-if="not blog_posts" class="container mb64">
<p class="css_editable_hidden">
<h1>No blog post yet.</h1>
</p>
<t groups="base.group_website_publisher">
<t groups="base.group_document_user">
<p>Click on "Content" on the top menu to write your first blog post.</p>
</t>
</t>
</div>
<t t-foreach="blog_posts" t-as="blog_post">
<div t-att-data-publish="blog_post.website_published and 'on' or 'off'">
<h2 class="text-center">
<a t-attf-href="#{post_url(blogpost=blog_post)}" t-field="blog_post.name"></a>
</h2>
<p class="post-meta text-muted text-center" name='blog_post_data'>
<span class="fa fa-calendar oe_date"> <span t-field="blog_post.create_date"/> &amp;nbsp;</span>
<span t-if="len(blog_post.message_ids) &gt; 0" class="fa fa-comment-o">
<a t-attf-href="#{post_url(blogpost=blog_post)}#comments">
<t t-if="len(blog_post.message_ids) &lt;= 1" ><t t-esc="len(blog_post.message_ids)"/> comment</t>
<t t-if="len(blog_post.message_ids) > 1"><t t-esc="len(blog_post.message_ids)"/> comments</t>
</a>
</span>
<span t-if="not blog_post.website_published" class="label label-danger">not published</span>
</p>
<div t-raw="blog_post.shortened_content" class="blog_content"/>
<hr/>
</div>
<div class="oe_structure">
<section class="mb0">
<div class="container">
<div class="row">
<t t-call="website.pager" >
<t t-set="classname">pull-right</t>
</t>
<div class="col-md-12 mb32 mt16 text-center">
<h1 t-field="blog.name"/>
<h3 class="text-muted" t-field="blog.subtitle"/>
</div>
</div>
</div>
</section>
</div>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2" t-ignore="True" id="main_column">
</t>
</t>
</template>
<div t-if="not blog_posts" class="container mb64">
<p class="css_editable_hidden">
<h1>No blog post yet.</h1>
</p>
<p groups="base.group_document_user">
Click on "Content" on the top menu to write your first blog post.
</p>
</div>
<!-- Options: Blog Post Summary: hide author -->
<template id="opt_blog_post_short_author" name="Author"
inherit_option_id="website_blog.blog_post_short">
<xpath expr="//span[@class='fa fa-calendar oe_date']" position="after">
<span class="fa fa-user"> By <span t-field="blog_post.create_uid"/> &amp;nbsp;</span>
</xpath>
<div t-foreach="blog_posts" t-as="blog_post" class="mb32">
<img class="img-circle pull-right mt16"
t-att-src="'/website/image?model=res.partner&amp;field=image_small&amp;id='+str(blog_post.create_uid.partner_id.id)"
style="width: 50px;"/>
<a t-attf-href="/blog/#{ slug(blog_post.blog_id) }/post/#{ slug(blog_post) }">
<h2 t-field="blog_post.name" class="mb4"/>
</a>
<div class="text-muted">
<h4
t-field="blog_post.sub_title"
class="mb4 mt4"/>
<p name='blog_post_data' class="mb0">
<span t-field="blog_post.create_uid.partner_id.name"/>
&#5760; <span t-field="blog_post.create_date" t-field-options='{"format": "MMMM yyyy"}'/>
<span t-if="len(blog_post.message_ids) &gt; 0">
&#5760; <t t-esc="len(blog_post.message_ids)"/>
<t t-if="len(blog_post.message_ids) &lt;= 1" >comment</t>
<t t-if="len(blog_post.message_ids) > 1">comments</t>
</span>
<span t-if="not blog_post.website_published" class="label label-danger">not published</span>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="oe_structure"/>
</t>
</template>
<!-- Option: Blog Post Summary: show tags -->
@@ -153,54 +173,81 @@
<!-- Blog Post Complete -->
<template id="blog_post_complete" name="Blog Post">
<t t-call="website_blog.index">
<t t-call="website_blog.index">
<t t-call="website.publish_management">
<t t-set="object" t-value="blog_post"/>
<t t-set="publish_edit" t-value="True"/>
<t t-set="action" t-value="'website_blog.action_blog_post'"/>
<li>
<form class="duplicate hidden" action="/blogpost/duplicate">
<input name="blog_post_id" t-att-value="blog_post.id"/>
</form>
<a href="#" class="duplicate" onclick="$(this).prev('form').submit()">Duplicate</a>
</li>
</t>
<div id="title">
<h1 class="text-center" t-field="blog_post.name"/>
<p class="post-meta text-muted text-center" name="blog_post_data">
<span class="fa fa-calendar oe_date"> <span t-field="blog_post.create_date"/> &amp;nbsp;</span>
<span t-if="len(blog_post.message_ids) &gt; 0" class="fa fa-comment-o"> With
<a t-attf-href="#comments">
<t t-if="len(blog_post.message_ids) &lt;= 1" ><t t-esc="len(blog_post.message_ids)"/> comment</t>
<t t-if="len(blog_post.message_ids) > 1"><t t-esc="len(blog_post.message_ids)"/> comments</t>
<div class="cover js_fullheight" id="title" t-attf-style="background-image: url(#{blog_post.content_image})" t-ignore="True">
<div class="container">
<div class="container text-right mt16">
<div class="btn-group css_non_editable_mode_hidden">
<a id="change_cover" class="btn btn-primary">
Change Cover
</a>
</span>
</p>
<a id="clear_cover" class="btn btn-danger">
<span class="fa fa-times"/>
</a>
</div>
<t t-call="website.publish_management">
<t t-set="object" t-value="blog_post"/>
<t t-set="publish_edit" t-value="True"/>
<li>
<form class="duplicate hidden" action="/blogpost/duplicate">
<input name="blog_post_id" t-att-value="blog_post.id"/>
</form>
<a href="#" class="duplicate" onclick="$(this).prev('form').submit()">Duplicate</a>
</li>
</t>
</div>
</div>
<div class="blog_title">
<h1 t-field="blog_post.name" id="blog_post_name" t-att-data-blog-id="blog_post.id"/>
<h2 t-field="blog_post.sub_title"/>
<p class="post-meta text-muted text-center" name="blog_post_data"/>
<div>
<img class="img-circle" t-att-src="'/website/image?model=res.partner&amp;field=image_small&amp;id='+str(blog_post.create_uid.partner_id.id)" style="width: 30px; margin-right: 10px;"/>
<small id="blog_author" t-field="blog_post.create_uid.partner_id.name"/><br/>
</div>
<div t-if="blog_post.content_image" id="blog_angle_down">
<strong><a href="#blog_content" class="fa fa-angle-down fa-3x fa-inverse mt32"/></strong>
</div>
</div>
</div>
<div t-field="blog_post.content"/>
<div id="blog_content" t-field="blog_post.content" class="mt32"/>
<section id="comments" class="container">
<section id="comments" class="read_width">
<hr/>
<ul class="media-list" id="comments-list">
<li t-foreach="blog_post.website_message_ids" t-as="message" class="media">
<span class="pull-left">
<img class="media-object img img-circle" t-att-src="'/website/image?model=mail.message&amp;field=author_avatar&amp;id='+str(message.id)" style="width: 30px"/>
</span>
<div class="media-body">
<img class="media-object pull-left" t-att-src="'/website/image?model=res.partner&amp;field=image_small&amp;id='+str(message.author_id.id)" style="width: 50px; margin-right: 10px;"/>
<div class="media-body">
<t t-call="website.publish_short">
<t t-set="object" t-value="message"/>
</t>
<h5 class="media-heading">
<span t-field="message.author_id"/> <small>on <span t-field="message.date"/></small>
</h5>
<div t-field="message.body"/>
</div>
<t t-call="website.publish_short">
<t t-set="object" t-value="message"/>
</t>
<strong t-field="message.author_id"/> <span class="text-muted">on <span t-field="message.date"/></span>
<div t-field="message.body"/>
</div>
</li>
</ul>
</section>
<t t-if="next_post">
<div class="cover cover_footer mb0 text-center" t-attf-style="background-image: url(#{next_post.content_image})" t-ignore="True">
<div class="blog_title">
<a class="hidden js_next" t-attf-href="/blog/#{ slug(next_post.blog_id) }/post/#{ slug(next_post) }/#wrap"/>
<h1 t-field="next_post.name"/>
<h2 t-field="next_post.sub_title"/>
<div>
<img class="img-circle" t-att-src="'/website/image?model=res.partner&amp;field=image_small&amp;id='+str(next_post.create_uid.partner_id.id)" style="width: 30px; margin-right: 10px;"/>
<small id="blog_author" t-field="next_post.create_uid.partner_id.name"/>
</div>
<p class="mt32">Read Next <span class="fa fa-long-arrow-right"/></p>
</div>
</div>
</t>
</t>
</template>
<template id="blog_breadcrumb" name="Breadcrumb"
@@ -222,39 +269,44 @@
</xpath>
</template>
<!-- Options: Blog Post: user can reply -->
<template id="opt_blog_post_complete_comment" name="Allow Comments"
inherit_option_id="website_blog.blog_post_complete" inherit_id="website_blog.blog_post_complete"
<template id="opt_blog_post_complete_comment" name="Allow blog post comment"
inherit_option_id="website_blog.blog_post_complete"
groups="website_mail.group_comment">
<xpath expr="//ul[@id='comments-list']" position="before">
<section class="mb32 css_editable_mode_hidden">
<section class="mb32 read_width css_editable_mode_hidden">
<form id="comment" t-attf-action="/blogpost/comment" method="POST">
<input name="blog_post_id" t-att-value="blog_post.id" type="hidden"/>
<img class="img pull-left img-rounded" t-att-src="'/website/image?model=res.partner&amp;field=image_small&amp;id='+str(user_id.partner_id.id)" style="width: 50px; margin-right: 10px;"/>
<div class="pull-left mb32" style="width: 75%%">
<textarea rows="3" name="comment" class="form-control" placeholder="Write a comment..."></textarea>
<button type="submit" class="btn btn-primary mt8">Post</button>
<div class="media">
<span class="pull-left">
<img class="img img-circle media-object" t-att-src="'/website/image?model=res.partner&amp;field=image_small&amp;id='+str(user_id.partner_id.id)" style="width: 30px"/>
</span>
<div class="media-body">
<input name="blog_post_id" t-att-value="blog_post.id" type="hidden"/>
<textarea rows="3" name="comment" class="form-control" placeholder="Write a comment..."></textarea>
<button type="submit" class="btn btn-primary mt8">Post</button>
</div>
</div>
</form>
</section>
<div class="clearfix"/>
</xpath>
</template>
<!-- Options: Blog Post: hide author -->
<template id="opt_blog_post_complete_author" name="Authors"
<!-- Options: Blog Post: user can select text for tweet -->
<template id="opt_blog_post_select_to_tweet" name="Select to Tweet"
inherit_option_id="website_blog.blog_post_complete">
<xpath expr="//span[@class='fa fa-calendar oe_date']" position="after">
<span class="fa fa-user"> By <span t-field="blog_post.create_uid"/> &amp;nbsp;</span>
<xpath expr="//div[@id='blog_content']" position="attributes">
<attribute name="class">js_tweet mt32</attribute>
</xpath>
<xpath expr="//div[@id='title']//div[@class='blog_title']" position="attributes">
<attribute name="class">blog_title js_tweet</attribute>
</xpath>
</template>
<!-- Options: Blog Post: show blog -->
<template id="opt_blog_post_complete_blog" name="Blog"
<!-- Options: Blog Post: user can add Inline Discussion -->
<template id="opt_blog_post_inline_discussion" name="Allow comment in text"
inherit_option_id="website_blog.blog_post_complete">
<xpath expr="//span[@class='fa fa-calendar oe_date']" position="after">
<span class="fa fa-folder-open"> In <span t-field="blog_post.blog_id"/> &amp;nbsp;</span>
<xpath expr="//div[@id='blog_content']" position="before">
<div class="js_discuss"/>
</xpath>
</template>
@@ -276,6 +328,9 @@
<t t-call="website.layout">
<t t-set="head">
<link rel='stylesheet' href='/website_blog/static/src/css/website_blog.css'/>
<script type="text/javascript" src="/website_blog/static/src/js/website_blog.inline.discussion.js"></script>
<script type="text/javascript" src="/website_blog/static/src/js/website_blog.js"/>
<script type="text/javascript" src="/website_blog/static/lib/contentshare.js"/>
</t>
<div id="wrap" class="js_blog">
<t t-raw="0"/>
@@ -283,23 +338,19 @@
</t>
</template>
<!-- Option: Right Column for extra info -->
<!-- Option:Right Column for extra info -->
<template id="index_right" name="Right Column"
inherit_option_id="website_blog.index">
<xpath expr="//div[@id='wrap']" position="replace">
<div class="container mt16 js_website_blog">
<div class="row">
<div class="col-lg-8 col-sm-8" id="blog_left_column">
<t t-raw="0"/>
</div>
<div class="col-lg-3 col-lg-offset-1 col-sm-4" id="blog_right_column"/>
</div>
</div>
inherit_option_id="website_blog.blog_post_short">
<xpath expr="//div[@id='main_column']" position="attributes">
<attribute name="class">col-sm-8</attribute>
</xpath>
<xpath expr="//div[@id='main_column']" position="after">
<div class="col-lg-3 col-lg-offset-1 col-sm-4" id="blog_right_column"/>
</xpath>
</template>
<!-- Option: Right Column: tags -->
<!-- Option:Right Column: tags -->
<template id="opt_blog_rc_tags" name="Tags"
inherit_option_id="website_blog.index_right">
<xpath expr="//div[@id='blog_right_column']" position="inside">
@@ -316,7 +367,7 @@
</xpath>
</template>
<!-- Option: Right Column: archives -->
<!-- Option:Right Column: archives -->
<template id="opt_blog_rc_history" name="Archives"
inherit_option_id="website_blog.index_right">
<xpath expr="//div[@id='blog_right_column']" position="inside">
@@ -333,7 +384,7 @@
</xpath>
</template>
<!-- Option: Right Column: about us -->
<!-- Option:Right Column: about us -->
<template id="opt_blog_rc_about_us" name="About Us" priority="2"
inherit_option_id="website_blog.index_right">
<xpath expr="//div[@id='blog_right_column']" position="inside">
@@ -350,7 +401,7 @@
</xpath>
</template>
<!-- Option: Right Column: follow us -->
<!-- Option:Right Column: follow us -->
<template id="opt_blog_rc_follow_us" name="Follow us" priority="4"
inherit_option_id="website_blog.index_right">
<xpath expr="//div[@id='blog_right_column']" position="inside">
@@ -377,7 +428,7 @@
</xpath>
</template>
<!-- Option: Right Column: blogs -->
<!-- Option:Right Column: blogs -->
<template id="opt_blog_rc_blogs" name="Our Blogs" priority="6"
inherit_option_id="website_blog.index_right">
<xpath expr="//div[@id='blog_right_column']" position="inside">
@@ -56,9 +56,15 @@
<sheet>
<h1><field name="name" placeholder="Name"/></h1>
<field name="tag_ids" widget="many2many_tags"/>
<field name="sub_title" placeholder="Blog Subtitle"/>
<group>
<field name="content_image"/>
<field name="blog_id"/>
</group>
<group>
<field name="visits"/>
<field name="ranking" invisible="1"/>
</group>
<field name="content" placeholder="e.g. Once upon a time..." widget="html"/>
<group string="Technical" groups="base.group_no_one">
<field name="write_uid" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_document_user']}"/>
@@ -155,5 +161,6 @@
name="Page History"
res_model="blog.post.history"
src_model="blog.post"/>
</data>
</openerp>