[REF] website_blog: refactore cover option and change opacity behavior

* Isolate website_blog style
* Simplify/Correct the cover option JS
* Allow to modify the cover from the blog list page
* Change cover layout (use a more conventionnal odoo design with a
div which is full width, which contains a container(-fluid) then its
content) -> easier to customize.
* Refactore code to be understandable
* Change behavior of opacity filter: before this commit the cover
filter was not intuitive and did not work on IE or Edge, it mixed
the color of the bg-image and the bg-color in a complex way and the
opacity was just controlling if the image was visible clearly or not
(which led in general to ugly style if the opacity was used). Now, the
color in applied *on top* of the image so that its color changes the
hue of the underlying image. The opacity value controls only the
opacity value of the color to mix.

[MIGRATION] Note: as the opacity behavior has changed, the exact same
behavior is not reproductible at all. But for the change to make a bit
of sense in old databases, this should be applied for the field
"cover_properties" of blog posts (with changes in layout):

if cover_properties.background-color != "oe_none":
    cover_properties.opacity = 0.6
else:
    cover_properties.opacity = 1.0 - cover_properties.opacity
This commit is contained in:
qsm-odoo
2016-08-19 17:44:28 +02:00
parent ee19cf08e4
commit 74d7de465e
7 changed files with 326 additions and 320 deletions
@@ -20,7 +20,7 @@
<field name="published_date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="website_meta_keywords">Odoo, email</field>
<field name="website_meta_description">The Future of Emails</field>
<field name="cover_properties">{"background-image": "url(/website_blog/static/src/img/library/flower_texture.jpg)", "background-color": "oe_yellow" ,"opacity": "1.0", "resize_class": "cover container cover_narrow"}</field>
<field name="cover_properties">{"background-image": "url(/website_blog/static/src/img/library/flower_texture.jpg)", "background-color": "oe_yellow" ,"opacity": "0.6", "resize_class": "cover container cover_narrow"}</field>
<field name="content"><![CDATA[
<div class="container">
<section class="mt16 mb16 readable">
@@ -124,7 +124,7 @@
<field name="website_published" eval="True"/>
<field name="published_date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="tag_ids" eval="[(6, 0, [ref('blog_tag_1'), ref('blog_tag_2')])]"/>
<field name="cover_properties">{"background-image": "url(/website/static/src/img/library/ship_sea.jpg)", "background-color": "oe_green" ,"opacity": "0.8", "resize_class": "cover cover_full"}</field>
<field name="cover_properties">{"background-image": "url(/website/static/src/img/library/ship_sea.jpg)", "background-color": "oe_green" ,"opacity": "0.6", "resize_class": "cover container-fluid cover_full"}</field>
<field name="content">
<![CDATA[<section><div class="container">
<div class="row">
+1 -1
View File
@@ -107,7 +107,7 @@ class BlogPost(models.Model):
active = fields.Boolean('Active', default=True)
cover_properties = fields.Text(
'Cover Properties',
default='{"background-image": "none", "background-color": "oe_none", "opacity": "0.6", "resize_class": ""}')
default='{"background-image": "none", "background-color": "oe_black", "opacity": "0.2", "resize_class": ""}')
blog_id = fields.Many2one('blog.blog', 'Blog', required=True, ondelete='cascade')
tag_ids = fields.Many2many('blog.tag', string='Tags')
content = fields.Html('Content', default=_default_content, translate=html_translate, sanitize=False)
@@ -13,7 +13,7 @@ contentMenu.TopBar.include({
new_blog_post: function () {
var model = new Model('blog.blog');
model.call('name_search', [], { context: base.get_context() }).then(function (blog_ids) {
if (blog_ids.length == 1) {
if (blog_ids.length === 1) {
document.location = '/blog/' + blog_ids[0][0] + '/post/new';
} else if (blog_ids.length > 1) {
website.prompt({
@@ -47,23 +47,22 @@ odoo.define('website_blog.editor', function (require) {
rte.Class.include({
// Destroy popOver and stop listening mouseup event on edit mode
start: function () {
var self = this;
$(".js_tweet, .js_comment").off('mouseup').trigger('mousedown');
return this._super.apply(this, arguments);
},
saveElement: function ($el, context) {
if ($el.is('.website_blog #title')) {
if ($el.is('.o_blog_cover_container')) {
return ajax.jsonRpc("/blog/post_change_background", 'call', {
'post_id' : +$el.find('#blog_post_name').data('oe-id'),
'post_id' : parseInt($el.closest("[name=\"blog_post\"], .website_blog").find("[data-oe-model=\"blog.post\"]").first().data("oe-id"), 10),
'cover_properties' : {
"background-image": $el.find('#js_blogcover').css("background-image").replace(/"/g, ''),
"background-color": $el.find('#js_blogcover').attr("class"),
"opacity": $el.find('#js_blogcover').css("opacity"),
"resize_class": $el.attr('class'),
"background-image": $el.children(".o_blog_cover_image").css("background-image").replace(/"/g, ''),
"background-color": $el.data("filter_color"),
"opacity": $el.data("filter_value"),
"resize_class": $el.data("cover_class"),
}
});
}
return this._super($el, context);
return this._super.apply(this, arguments);
},
});
@@ -84,59 +83,66 @@ odoo.define('website_blog.editor', function (require) {
}
});
options.registry.website_blog = options.Class.extend({
start : function() {
this.$cover = this.$target.find('#js_blogcover');
this.src = this.$target.css("background-image").replace(/url\(|\)|"|'/g,'').replace(/.*none$/,'');
this.$image = $('<image src="'+this.src+'">');
this._super();
options.registry.blog_cover = options.Class.extend({
init: function () {
this._super.apply(this, arguments);
this.$image = this.$target.children(".o_blog_cover_image");
this.$filter = this.$target.children(".o_blog_cover_filter");
},
clear : function(type, value, $li) {
clear: function (type, value, $li) {
if (type !== 'click') return;
this.src = null;
this.$cover.css({"background-image": '', 'min-height': ''});
this.$image.removeAttr("src");
this.$target.removeClass('cover cover_full cover_narrow cover_midscreen cover_mid_narrow');
this.select_class(type, "", $());
this.$image.css("background-image", "");
this.$target.addClass("o_dirty");
},
change : function(type, value, $li) {
change: function (type, value, $li) {
if (type !== 'click') return;
var self = this;
var editor = new widget.MediaDialog(null, {only_images: true}, this.$image, this.$image[0]).open();
editor.on('saved', self, function (event, img) {
var url = self.$image.attr('src');
self.$cover.css({"background-image": url ? 'url(' + url + ')' : ""});
self.$target.addClass('o_dirty cover cover_full');
self.set_active();
var $image = $("<img/>", {src: this.$image.css("background-image")});
var editor = new widget.MediaDialog(null, {only_images: true}, $image, $image[0]).open();
editor.on("saved", this, function (event, img) {
var src = $image.attr("src");
this.$image.css("background-image", src ? ("url(" + src + ")") : "");
if (!this.$target.hasClass("cover")) {
var $li = this.$el.find("[data-select_class]").first();
this.select_class(type, $li.data("select_class"), $li);
}
this.set_active();
this.$target.addClass("o_dirty");
});
},
cover_class : function(type, value, $li) {
this.$target.attr("class", (type === 'over' || type === 'click') ? value : this.class);
filter_value: function (type, value, $li) {
this.$filter.css("opacity", value);
this.$target.addClass('o_dirty');
},
opacity : function(type, value, $li) {
this.$cover.css("opacity", (type === 'over' || type === 'click') ? value : this.value);
this.$target.addClass('o_dirty');
},
bgcolor : function(type, value, $li) {
this.$cover.attr("class", (type === 'over' || type === 'click') ? value : this.background);
this.$target.addClass('o_dirty');
},
set_active: function(){
this._super();
this.background = this.$cover.attr("class");
this.class = this.$target.attr('class');
this.value = this.$cover.css('opacity');
this.$el.parent().find('.snippet-option-website_blog:not(li[data-change])').toggleClass("hidden", !this.$target.hasClass("cover"));
this.$el.find('li[data-bgcolor], li[data-opacity], li[data-cover_class]').removeClass("active");
this.$el.find('[data-bgcolor="' + this.background + '"], [data-opacity="' + parseFloat(this.value).toFixed(1) + '"]').addClass("active");
if ((this.class || '').indexOf('cover_narrow') != -1) {
this.$el.find('[data-cover_class*=cover_narrow]').addClass("active");
} else if ((this.class || '').indexOf('cover_midscreen') != -1) {
this.$el.find('[data-cover_class*=cover_midscreen]').addClass("active");
} else {
this.$el.find('[data-cover_class*=cover_full]').addClass("active");
filter_color: function (type, value, $li) {
var $lis = this.$el.find("[data-filter_color]").addBack("[data-filter_color]");
var classes = $lis.map(function () {return $(this).data("filter_color");}).get().join(" ");
this.$filter.removeClass(classes);
if (value) {
this.$filter.addClass(value);
}
this.$target.addClass("o_dirty");
},
set_active: function () {
this._super.apply(this, arguments);
var self = this;
this.$el.filter(":not([data-change])").toggleClass("hidden", !this.$target.hasClass("cover"));
var $actives = this.$el.find('li[data-filter_value], li[data-filter_color]').removeClass("active")
.filter(function () {
var data = $(this).data();
return (parseFloat(data.filter_value).toFixed(1) === parseFloat(self.$filter.css('opacity')).toFixed(1)
|| self.$filter.hasClass(data.filter_color));
}).addClass("active");
this.$target.data("cover_class", this.$el.find(".active[data-select_class]").data("select_class") || "");
this.$target.data("filter_value", $actives.filter("[data-filter_value]").data("filter_value") || 0.0);
this.$target.data("filter_color", $actives.filter("[data-filter_color]").data("filter_color") || "");
},
});
});
@@ -1,8 +1,6 @@
odoo.define('website_blog.website_blog', function (require) {
"use strict";
var ajax = require('web.ajax');
function page_transist(event) {
event.preventDefault();
var newLocation = $('.js_next')[0].href;
@@ -37,9 +35,9 @@ function shareArticle(event){
url = 'https://www.facebook.com/sharer/sharer.php?u='+window.location.href;
} else if ($(this).hasClass('o_linkedin_complete')){
url = 'https://www.linkedin.com/shareArticle?mini=true&url='+window.location.href+'&title='+blog_title_complete;
} else{
} else {
url = 'https://plus.google.com/share?url='+window.location.href;
};
}
}
else {
var blog_post = $(this).parents("[name='blog_post']");
@@ -71,7 +69,6 @@ $(document).ready(function() {
function() { $('div.o_blog_post_complete a').not('#'+this.id).addClass('unhover'); },
function() { $('div.o_blog_post_complete a').not('#'+this.id).removeClass('unhover'); }
);
});
});
});
@@ -1,224 +1,221 @@
.css_website_mail {
.has-error {
border-color: red;
}
.css_nav_month {
display: none;
&:first-of-type {
display: block;
.website_blog {
.css_website_mail {
.has-error {
border-color: red;
}
.css_nav_month {
display: none;
&:first-of-type {
display: block;
}
}
}
}
.read_width {
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.blog_content {
min-height: 350px !important;
a.oe_mail_expand:after {
content: " →";
.read_width {
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
a.oe_mail_expand {
font-weight: bold;
.blog_content {
min-height: 350px !important;
a.oe_mail_expand:after {
content: " →";
}
a.oe_mail_expand {
font-weight: bold;
}
}
}
p.post-meta {
position: relative;
top: -5px;
}
p.post-meta {
position: relative;
top: -5px;
}
div#blog_angle_down {
a:hover {
div#blog_angle_down a:hover {
text-decoration: none;
}
}
.cover {
color: white;
position: relative;
.blog_title {
position: absolute;
}
}
.o_blog_cover_container {
position: relative;
.blog_title {
text-align: center;
top: 20%;
margin-right: auto;
margin-left: auto;
left: 0;
right: 0;
h1 {
font-weight: bold;
}
}
> .o_blog_cover_component {
.o-position-absolute(0, 0, 0, 0);
display: none;
.cover_full {
height: 100vh;
}
.o-background-size(cover);
background-position: center;
background-repeat: no-repeat;
}
.cover_midscreen {
height: 50vh;
}
> .blog_title {
margin: 0 auto;
text-align: center;
font-weight: bold;
}
&.cover {
> .o_blog_cover_component {
display: block;
}
}
&.cover, &.cover_footer {
> .blog_title {
color: white;
.o-position-absolute(20%, @grid-gutter-width, auto, @grid-gutter-width);
}
}
.cover_narrow {
height: 50vh;
overflow: hidden;
}
&.cover_full {
height: 600px;
height: 100vh;
}
&.cover_narrow {
height: 300px;
height: 50vh;
}
&.o_list_cover {
display: none;
width: auto!important;
height: 250px!important;
.cover_footer_bg {
min-height: 350px;
height: 65vh;
}
&.cover {
display: block;
}
}
/* mobile preview: for blog h1,h2 font-size and cover-footer height of image overlapas */
@media (max-width: 768px) {
.blog_title {
h1 {
font-size: 26px;
&.cover_footer {
min-height: 350px;
height: 65vh;
background-color: #B8B8B8;
cursor: pointer;
}
}
.blog_title {
h2 {
font-size: 20px;
/* mobile preview: for blog h1,h2 font-size and cover-footer height of image overlapas */
@media (max-width: @screen-xs-max) {
.o_blog_cover_container {
> .blog_title {
> h1 {
font-size: 26px;
}
> h2 {
font-size: 20px;
}
}
&.cover > .blog_title {
top: 10%;
}
&.cover_narrow {
height: 65vh;
}
&.cover_footer {
min-height: 280px;
height: 50vh;
> .blog_title {
top: 2%;
}
}
}
}
.cover_narrow {
height: 65vh;
}
#title {
.blog_title {
top: 10%;
}
}
.cover_footer {
min-height: 280px;
height: 50vh;
}
.cover_footer {
.blog_title {
top: 2%;
}
}
}
mark + .popover, .cover_footer {
cursor: pointer;
}
.blog_publish_btn {
padding-top: 16px;
}
.cover_footer_bg[style*="background-image: none;"] {
background-color: #B8B8B8;
}
#js_blogcover {
background-blend-mode: multiply;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
height: 100%;
}
.o_blog_post_title {
font-size: 24px;
}
.o_blog_post_teaser {
text-align: justify;
}
/*To display the grid or inline presentation of the blog.post_list*/
.o_grid {
margin: 0 6% 6% 0;
border: 1px solid #EEEEEE;
box-shadow: .5px .5px .5px .5px rgba(238,238,238,1);
padding-bottom: 15px;
.o_blog_post_teaser {
width: 100%;
}
> .text-muted > .mb0 > hr {
display: none;
}
}
#js_blogcover {
height: 150px;
opacity: 1 !important;
}
.o_author_avatar_little {
width: 40px;
display: inline;
margin-top: -5px;
}
/* Sharing links style */
.o_sharing_links {
margin-top: 20px;
> p {
display: inline;
font-size: 12px;
}
> a {
color: #b3b3b3;
font: normal normal normal 28px/1 FontAwesome;
margin: 0 4px 0 4px;
mark + .popover, .cover_footer {
cursor: pointer;
&:hover {
text-decoration: none;
}
.js_publish_management {
.o-position-absolute(@grid-gutter-width/2, @grid-gutter-width/2);
z-index: 1;
.dropdown-menu {
left: auto;
right: 0;
}
&.o_twitter_complete, &.o_twitter:hover {
color: #4099FF;
}
.o_blog_post_title {
font-size: 24px;
}
.o_blog_post_teaser {
text-align: justify;
}
/*To display the grid or inline presentation of the blog.post_list*/
.o_grid {
margin: 0 6% 6% 0;
border: 1px solid #EEEEEE;
box-shadow: .5px .5px .5px .5px rgba(238,238,238,1);
padding-bottom: 15px;
.o_blog_post_teaser {
width: 100%;
}
&.o_google_complete, &.o_google:hover {
color: #DD4B39;
> .text-muted > .mb0 > hr {
display: none;
}
&.o_facebook_complete, &.o_facebook:hover {
color: #3b5998;
}
.o_author_avatar_little {
width: 40px;
display: inline;
margin-top: -5px;
}
/* Sharing links style */
.o_sharing_links {
margin-top: 20px;
> p {
display: inline;
font-size: 12px;
}
&.o_linkedin_complete, &.o_linkedin:hover {
color: #0E76A8;
}
&.unhover {
> a {
color: #b3b3b3;
font: normal normal normal 28px/1 FontAwesome;
margin: 0 4px 0 4px;
cursor: pointer;
&:hover {
text-decoration: none;
}
&.o_twitter_complete, &.o_twitter:hover {
color: #4099FF;
}
&.o_google_complete, &.o_google:hover {
color: #DD4B39;
}
&.o_facebook_complete, &.o_facebook:hover {
color: #3b5998;
}
&.o_linkedin_complete, &.o_linkedin:hover {
color: #0E76A8;
}
&.unhover {
color: #b3b3b3;
}
}
}
}
.o_blog_post_complete.o_sharing_links {
max-width: 700px;
margin: 50px auto 50px auto;
text-align: center;
.o_blog_post_complete.o_sharing_links {
max-width: 700px;
margin: 50px auto 50px auto;
text-align: center;
> p {
font-size: 16px;
font-weight: 600;
> p {
font-size: 16px;
font-weight: 600;
}
> a {
font: normal normal normal 40px/1 FontAwesome;
}
}
> a {
font: normal normal normal 40px/1 FontAwesome;
}
}
div {
&[name="blog_post_data"] {
div[name="blog_post_data"] {
margin-top: 20px !important;
font-size: 13px;
}
&[name="blog_post"] {
div[name="blog_post"] {
position: relative;
hr {
margin-top: 10px;
+21 -25
View File
@@ -1,44 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="website_blog" inherit_id="website.snippets" name="Snippet Blog">
<template id="website_blog" inherit_id="website.snippets" name="Snippet Blog">
<xpath expr="//div[@id='snippet_options']" position="inside">
<div data-js='website_blog'
data-selector=".js_blog #title"
data-no-check="true">
<li data-change="true"> <a href="#">Change Cover</a> </li>
<div data-js="blog_cover" data-selector=".o_blog_cover_container" data-no-check="true">
<li data-change="true"><a href="#">Change Cover</a></li>
<li data-clear="true"><a href="#" >No Cover</a></li>
<li class="dropdown-submenu">
<a href="#">Size</a>
<ul class="dropdown-menu">
<li data-cover_class="cover cover_full"><a>Full Screen</a></li>
<li data-cover_class="cover cover_midscreen"><a>Mid screen</a></li>
<li data-cover_class="cover container cover_narrow"><a>Narrow</a></li>
<li data-select_class="cover container-fluid cover_full"><a href="#">Full Screen</a></li>
<li data-select_class="cover container-fluid cover_narrow"><a href="#">Mid screen</a></li>
<li data-select_class="cover container cover_narrow"><a href="#">Narrow</a></li>
</ul>
</li>
<li class="dropdown-submenu">
<a href="#">Color</a>
<a href="#">Filter Intensity</a>
<ul class="dropdown-menu">
<li data-bgcolor="oe_blue"><a>Blue</a></li>
<li data-bgcolor="oe_yellow"><a>Yellow</a></li>
<li data-bgcolor="oe_red"><a>Red</a></li>
<li data-bgcolor="oe_purple"><a>Purple</a></li>
<li data-bgcolor="oe_green"><a>Green</a></li>
<li data-bgcolor="oe_none"><a>None</a></li>
<li data-filter_value="0.0"><a href="#">None</a></li>
<li data-filter_value="0.2"><a href="#">Low</a></li>
<li data-filter_value="0.4"><a href="#">Medium</a></li>
<li data-filter_value="0.6"><a href="#">High</a></li>
</ul>
</li>
<li class="dropdown-submenu">
<a href="#">Opacity</a>
<a href="#">Filter Color</a>
<ul class="dropdown-menu">
<li data-opacity="1.0"><a>None</a></li>
<li data-opacity="0.8"><a>Low</a></li>
<li data-opacity="0.6"><a>Medium</a></li>
<li data-opacity="0.4"><a>High</a></li>
<li data-filter_color="oe_black"><a href="#">Black</a></li>
<li data-filter_color="oe_none"><a href="#">White</a></li>
<li data-filter_color="oe_blue"><a href="#">Blue</a></li>
<li data-filter_color="oe_yellow"><a href="#">Yellow</a></li>
<li data-filter_color="oe_red"><a href="#">Red</a></li>
<li data-filter_color="oe_purple"><a href="#">Purple</a></li>
<li data-filter_color="oe_green"><a href="#">Green</a></li>
</ul>
</li>
<li data-clear="true"> <a href="#" >No Cover</a></li>
</div>
</xpath>
</template>
</template>
</odoo>
@@ -179,12 +179,21 @@
</t>
</template>
<template id="blog_cover">
<div t-attf-class="o_blog_cover_container #{cover_properties.get('resize_class')} #{additionnal_classes or ''}">
<div class="o_blog_cover_component o_blog_cover_image" t-attf-style="background-image: #{cover_properties.get('background-image')};"/>
<div t-attf-class="o_blog_cover_component o_blog_cover_filter #{cover_properties.get('background-color')}" t-attf-style="opacity: #{cover_properties.get('opacity', 0.0)};"/>
<t t-raw="0"/>
</div>
</template>
<!-- Option: Blog Post List: cover image -->
<template id="opt_blog_post_cover_image" name="Cover image"
customize_show="True" active="True" inherit_id="website_blog.blog_post_short">
<xpath expr="//h2[@t-field='blog_post.name']/.." position="before">
<t t-if="blog_posts_cover_properties[blog_post_index].get('background-image', 'none') != 'none'">
<div id="js_blogcover" t-attf-class="#{blog_posts_cover_properties[blog_post_index].get('background-color')}" t-attf-style="background-image: #{blog_posts_cover_properties[blog_post_index].get('background-image', 'none')};opacity:1; height:250px; margin-top: 15px; margin-bottom: 30px;"></div>
<t t-call="website_blog.blog_cover">
<t t-set="cover_properties" t-value="blog_posts_cover_properties[blog_post_index]"/>
<t t-set="additionnal_classes" t-value="'o_list_cover mt16 mb32'"/>
</t>
</xpath>
</template>
@@ -207,42 +216,41 @@
</xpath>
</template>
<!-- Blog Post Complete -->
<template id="blog_post_complete" name="Blog Post">
<t t-call="website_blog.index">
<div class="container blog_publish_btn">
<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="/blog/post_duplicate" method="POST">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<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 t-attf-class="#{blog_post_cover_properties.get('resize_class', '')}" id="title" t-ignore="True">
<div id="js_blogcover" t-attf-class="#{blog_post_cover_properties.get('background-color')}" t-attf-style="background-image: #{blog_post_cover_properties.get('background-image', 'none')};opacity:#{blog_post_cover_properties.get('opacity', 1)}"></div>
<div class="blog_title">
<h1 t-field="blog_post.name" id="blog_post_name" t-att-data-blog-id="blog_post.id" placeholder="Blog Post Title"/>
<h2 t-field="blog_post.subtitle" placeholder="Subtitle"/>
<p class="post-meta text-muted text-center" name="blog_post_data"/>
<p class="post-meta text-muted text-center" t-if="len(blog_post.tag_ids)">
<span class="fa fa-tags"/>
<t t-foreach="blog_post.tag_ids" t-as="one_tag">
<a class="label label-primary mr8" t-attf-href="#{blog_url(tag=one_tag.id)}" t-esc="one_tag.name"/>
</t>
</p>
<div t-if="blog_post_cover_properties.get('resize_class') == 'cover cover_full'" id="blog_angle_down">
<strong><a href="#blog_content" class="fa fa-angle-down fa-3x fa-inverse mt4"/></strong>
</div>
<div id="title" class="blog_header" t-ignore="True">
<div class="container" style="position: relative;">
<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="/blog/post_duplicate" method="POST">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<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>
<t t-call="website_blog.blog_cover">
<t t-set="cover_properties" t-value="blog_post_cover_properties"/>
<div class="blog_title">
<h1 t-field="blog_post.name" id="blog_post_name" t-att-data-blog-id="blog_post.id" placeholder="Blog Post Title"/>
<h2 t-field="blog_post.subtitle" placeholder="Subtitle"/>
<p class="post-meta text-muted text-center" name="blog_post_data"/>
<p class="post-meta text-muted text-center" t-if="len(blog_post.tag_ids)">
<span class="fa fa-tags"/>
<t t-foreach="blog_post.tag_ids" t-as="one_tag">
<a class="label label-primary mr8" t-attf-href="#{blog_url(tag=one_tag.id)}" t-esc="one_tag.name"/>
</t>
</p>
<div t-if="'cover_full' in blog_post_cover_properties.get('resize_class', '')" id="blog_angle_down">
<strong><a href="#blog_content" class="fa fa-angle-down fa-3x fa-inverse mt4"/></strong>
</div>
</div>
</t>
</div>
<div id="blog_content" t-field="blog_post.content" class="blog_content mt32"/>
@@ -294,25 +302,27 @@
inherit_id="website_blog.blog_post_complete" active="True" customize_show="True">
<xpath expr="//div[@id='comments']|//div[@class='o_blog_post_complete o_sharing_links']" position="after">
<t t-if="next_post">
<div class="cover cover_footer mb0 text-center" t-ignore="True">
<div id="js_blogcover" t-attf-class="cover_footer_bg #{next_post_cover_properties.get('background-color')}" t-attf-style="background-image: #{next_post_cover_properties.get('background-image')};opacity:#{next_post_cover_properties.get('opacity')}"></div>
<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" placeholder="Blog Post Title"/>
<h2 t-field="next_post.subtitle" placeholder="Subtitle"/>
<div>
<t t-if="next_post.author_avatar">
<span t-field="next_post.author_avatar" t-field-options='{"widget": "image", "class": "img-circle", "style":"width: 30px; margin-right: 10px; display:inline"}' />
</t>
<span t-field="next_post.author_id" style="display: inline-block;" t-field-options='{
<t t-call="website_blog.blog_cover">
<t t-set="cover_properties" t-value="next_post_cover_properties"/>
<t t-set="additionnal_classes" t-value="'cover_footer'"/>
<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" placeholder="Blog Post Title"/>
<h2 t-field="next_post.subtitle" placeholder="Subtitle"/>
<div>
<t t-if="next_post.author_avatar">
<span t-field="next_post.author_avatar" t-field-options='{"widget": "image", "class": "img-circle", "style":"width: 30px; margin-right: 10px; display:inline"}' />
</t>
<span t-field="next_post.author_id" style="display: inline-block;" t-field-options='{
"widget": "contact",
"fields": ["name"]
}'/>
</div>
<p class="mt32">Read Next <span class="fa fa-long-arrow-right"/></p>
</div>
<p class="mt32">Read Next <span class="fa fa-long-arrow-right"/></p>
</div>
</div>
</t>
</t>
</t>
</xpath>
</template>