Merge pull request #229 from mailpoet/editor_posts
Editor: Posts widget
This commit is contained in:
@ -19,6 +19,10 @@ $divider-hover-border-color = $primary-active-color
|
||||
width: 100%
|
||||
border: 1px solid transparent
|
||||
|
||||
.mailpoet_active_divider_style
|
||||
border: 1px solid $active-divider-border-color
|
||||
background: $active-divider-background-color
|
||||
|
||||
.mailpoet_field_divider_style:hover
|
||||
border: 1px solid $divider-hover-border-color
|
||||
|
||||
|
@ -1,15 +1,12 @@
|
||||
.mailpoet_posts_block
|
||||
box-shadow(none)
|
||||
padding-left: 0
|
||||
padding-right: 0
|
||||
|
||||
& > .mailpoet_content
|
||||
font-size: 1em
|
||||
text-align: center
|
||||
background-color: $primary-active-color
|
||||
margin: 20px 0
|
||||
padding: 15px
|
||||
box-shadow(inset 1px 2px 1px $primary-inset-shadow-color)
|
||||
color: $white-color
|
||||
border-radius(3px)
|
||||
.mailpoet_posts_block_posts
|
||||
overflow: auto
|
||||
|
||||
& > .mailpoet_block
|
||||
width: 100%
|
||||
|
||||
.mailpoet_post_selection_filter_row
|
||||
margin-top: 5px
|
||||
|
@ -214,6 +214,7 @@ define([
|
||||
this.model.set(field, value);
|
||||
},
|
||||
onBeforeDestroy: function() {
|
||||
console.log('Calling close');
|
||||
MailPoet.Modal.close();
|
||||
},
|
||||
});
|
||||
|
@ -31,7 +31,7 @@ define([
|
||||
base = BaseBlock;
|
||||
|
||||
Module.PostsBlockModel = base.BlockModel.extend({
|
||||
stale: ['_selectedPosts', '_availablePosts'],
|
||||
stale: ['_selectedPosts', '_availablePosts', '_transformedPosts'],
|
||||
defaults: function() {
|
||||
return this._getDefaults({
|
||||
type: 'posts',
|
||||
@ -63,6 +63,7 @@ define([
|
||||
divider: {},
|
||||
_selectedPosts: [],
|
||||
_availablePosts: [],
|
||||
_transformedPosts: new (App.getBlockTypeModel('container'))(),
|
||||
}, App.getConfig().get('blockDefaults.posts'));
|
||||
},
|
||||
relations: function() {
|
||||
@ -71,15 +72,26 @@ define([
|
||||
divider: App.getBlockTypeModel('divider'),
|
||||
_selectedPosts: Backbone.Collection,
|
||||
_availablePosts: Backbone.Collection,
|
||||
_transformedPosts: App.getBlockTypeModel('container'),
|
||||
};
|
||||
},
|
||||
initialize: function() {
|
||||
var that = this;
|
||||
var that = this,
|
||||
POST_REFRESH_DELAY_MS = 500,
|
||||
refreshAvailablePosts = _.debounce(this.fetchAvailablePosts.bind(this), POST_REFRESH_DELAY_MS),
|
||||
refreshTransformedPosts = _.debounce(this._refreshTransformedPosts.bind(this), POST_REFRESH_DELAY_MS);
|
||||
|
||||
// Attach Radio.Requests API primarily for highlighting
|
||||
_.extend(this, Radio.Requests);
|
||||
|
||||
this.fetchAvailablePosts();
|
||||
this.on('change:amount change:contentType change:terms change:inclusionType change:postStatus change:search change:sortBy', this._scheduleFetchAvailablePosts, this);
|
||||
this.on('change:amount change:contentType change:terms change:inclusionType change:postStatus change:search change:sortBy', refreshAvailablePosts);
|
||||
|
||||
this.listenTo(this.get('_selectedPosts'), 'add remove reset', refreshTransformedPosts);
|
||||
this.on('change:displayType change:titleFormat change:titlePosition change:titleAlignment change:titleIsLink change:imagePadded change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:showDivider', refreshTransformedPosts);
|
||||
this.listenTo(this.get('readMoreButton'), 'change', refreshTransformedPosts);
|
||||
this.listenTo(this.get('divider'), 'change', refreshTransformedPosts);
|
||||
|
||||
this.on('insertSelectedPosts', this._insertSelectedPosts, this);
|
||||
},
|
||||
fetchAvailablePosts: function() {
|
||||
@ -93,20 +105,23 @@ define([
|
||||
console.log('Posts fetchPosts error', arguments);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Batch more changes during a specific time, instead of fetching
|
||||
* ALC posts on each model change
|
||||
*/
|
||||
_scheduleFetchAvailablePosts: function() {
|
||||
var timeout = 500,
|
||||
that = this;
|
||||
if (this._fetchPostsTimer !== undefined) {
|
||||
clearTimeout(this._fetchPostsTimer);
|
||||
_refreshTransformedPosts: function() {
|
||||
var that = this,
|
||||
data = this.toJSON();
|
||||
|
||||
data.posts = this.get('_selectedPosts').pluck('ID');
|
||||
|
||||
if (data.posts.length === 0) {
|
||||
this.get('_transformedPosts.blocks').reset();
|
||||
return;
|
||||
}
|
||||
this._fetchPostsTimer = setTimeout(function() {
|
||||
that.fetchAvailablePosts();
|
||||
that._fetchPostsTimer = undefined;
|
||||
}, timeout);
|
||||
|
||||
WordpressComponent.getTransformedPosts(data).done(function(posts) {
|
||||
console.log('Transformed posts fetched', arguments);
|
||||
that.get('_transformedPosts').get('blocks').reset(posts, {parse: true});
|
||||
}).fail(function() {
|
||||
console.log('Posts _refreshTransformedPosts error', arguments);
|
||||
});
|
||||
},
|
||||
_insertSelectedPosts: function() {
|
||||
var that = this,
|
||||
@ -131,6 +146,9 @@ define([
|
||||
className: "mailpoet_block mailpoet_posts_block mailpoet_droppable_block",
|
||||
getTemplate: function() { return templates.postsBlock; },
|
||||
modelEvents: {},
|
||||
regions: _.extend({
|
||||
postsRegion: '.mailpoet_posts_block_posts',
|
||||
}, base.BlockView.prototype.regions),
|
||||
onDragSubstituteBy: function() { return Module.PostsWidgetView; },
|
||||
initialize: function() {
|
||||
base.BlockView.prototype.initialize.apply(this, arguments);
|
||||
@ -142,6 +160,13 @@ define([
|
||||
this.toolsRegion.show(this.toolsView);
|
||||
}
|
||||
this.trigger('showSettings');
|
||||
|
||||
var ContainerView = App.getBlockTypeView('container'),
|
||||
renderOptions = {
|
||||
disableTextEditor: true,
|
||||
disableDragAndDrop: true,
|
||||
};
|
||||
this.postsRegion.show(new ContainerView({ model: this.model.get('_transformedPosts'), renderOptions: renderOptions }));
|
||||
},
|
||||
notifyAboutSelf: function() {
|
||||
return this;
|
||||
@ -216,6 +241,7 @@ define([
|
||||
insertPosts: function() {
|
||||
this.model.trigger('insertSelectedPosts');
|
||||
this.model.destroy();
|
||||
this.close();
|
||||
},
|
||||
});
|
||||
|
||||
@ -307,11 +333,6 @@ define([
|
||||
},
|
||||
}).trigger( 'change' );
|
||||
},
|
||||
onBeforeDestroy: function() {
|
||||
base.BlockSettingsView.prototype.onBeforeDestroy.apply(this, arguments);
|
||||
// Force close select2 if it hasn't closed yet
|
||||
this.$('.mailpoet_posts_categories_and_tags').select2('close');
|
||||
},
|
||||
changeField: function(field, event) {
|
||||
this.model.set(field, jQuery(event.target).val());
|
||||
},
|
||||
|
@ -56,7 +56,7 @@ define([
|
||||
};
|
||||
|
||||
Module.getTransformedPosts = function(options) {
|
||||
return Module._cachedQuery({
|
||||
return Module._query({
|
||||
action: 'getTransformedPosts',
|
||||
options: options,
|
||||
});
|
||||
|
@ -50,9 +50,11 @@ class MetaInformationManager {
|
||||
// check if the user specified a label to be displayed before the author's name
|
||||
if(strlen($preceded_by) > 0) {
|
||||
$content = stripslashes($preceded_by) . ' ';
|
||||
} else {
|
||||
$content = '';
|
||||
}
|
||||
|
||||
return join(', ', $categories);
|
||||
return $content . join(', ', $categories);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
@ -24,14 +24,24 @@ class PostTransformer {
|
||||
$structure_transformer = new StructureTransformer();
|
||||
$structure = $structure_transformer->transform($content, (bool)$this->args['imagePadded']);
|
||||
|
||||
$structure = $this->appendFeaturedImage($post, (bool)$this->args['imagePadded'], $structure);
|
||||
$structure = $this->appendFeaturedImage(
|
||||
$post,
|
||||
$this->args['displayType'],
|
||||
$this->args['imagePadded'] === 'true',
|
||||
$structure
|
||||
);
|
||||
$structure = $this->appendPostTitle($post, $structure);
|
||||
$structure = $this->appendReadMore($post->ID, $structure);
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
private function appendFeaturedImage($post, $image_padded, $structure) {
|
||||
private function appendFeaturedImage($post, $display_type, $image_padded, $structure) {
|
||||
if ($display_type === 'full') {
|
||||
// No featured images for full posts
|
||||
return $structure;
|
||||
}
|
||||
|
||||
$featured_image = $this->getFeaturedImage(
|
||||
$post->ID,
|
||||
$post->post_title,
|
||||
@ -68,7 +78,7 @@ class PostTransformer {
|
||||
|
||||
return array(
|
||||
'type' => 'image',
|
||||
'link' => '',
|
||||
'link' => get_permalink($post_id),
|
||||
'src' => $image_info[0],
|
||||
'alt' => $alt_text,
|
||||
'padded' => $image_padded,
|
||||
@ -84,6 +94,8 @@ class PostTransformer {
|
||||
}
|
||||
|
||||
private function appendPostTitle($post, $structure) {
|
||||
$title = $this->getPostTitle($post);
|
||||
|
||||
if ($this->args['titlePosition'] === 'inTextBlock') {
|
||||
// Attach title to the first text block
|
||||
$text_block_index = null;
|
||||
@ -94,7 +106,6 @@ class PostTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
$title = $this->getPostTitle($post);
|
||||
if ($text_block_index === null) {
|
||||
$structure[] = array(
|
||||
'type' => 'text',
|
||||
@ -103,6 +114,14 @@ class PostTransformer {
|
||||
} else {
|
||||
$structure[$text_block_index]['text'] = $title . $structure[$text_block_index]['text'];
|
||||
}
|
||||
} elseif ($this->args['titlePosition'] === 'aboveBlock') {
|
||||
array_unshift(
|
||||
$structure,
|
||||
array(
|
||||
'type' => 'text',
|
||||
'text' => $title,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $structure;
|
||||
@ -113,6 +132,15 @@ class PostTransformer {
|
||||
$button = $this->args['readMoreButton'];
|
||||
$button['url'] = get_permalink($post_id);
|
||||
$structure[] = $button;
|
||||
} else {
|
||||
$structure[] = array(
|
||||
'type' => 'text',
|
||||
'text' => sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
get_permalink($post_id),
|
||||
$this->args['readMoreText']
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $structure;
|
||||
@ -121,7 +149,7 @@ class PostTransformer {
|
||||
private function getPostTitle($post) {
|
||||
$title = $post->post_title;
|
||||
|
||||
if ((bool)$this->args['titleIsLink']) {
|
||||
if ($this->args['titleIsLink'] === 'true') {
|
||||
$title = '<a href="' . get_permalink($post->ID) . '">' . $title . '</a>';
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
define([
|
||||
'newsletter_editor/App',
|
||||
'newsletter_editor/components/wordpress',
|
||||
'newsletter_editor/blocks/posts',
|
||||
'newsletter_editor/blocks/posts'
|
||||
], function(EditorApplication, WordpressComponent, PostsBlock) {
|
||||
|
||||
describe('Posts', function () {
|
||||
@ -373,12 +373,7 @@ define([
|
||||
});
|
||||
|
||||
describe('when "title as list" is selected', function() {
|
||||
var model, view;
|
||||
beforeEach(function() {
|
||||
model = new (PostsBlock.PostsBlockModel)();
|
||||
model.request = sinon.stub().returns({$el: {}});
|
||||
view = new (PostsBlock.PostsBlockSettingsView)({model: model});
|
||||
view.render();
|
||||
view.$('.mailpoet_posts_display_type').val('titleOnly').change();
|
||||
view.$('.mailpoet_posts_title_format').val('ul').change();
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="mailpoet_tools"></div>
|
||||
<div class="mailpoet_content">
|
||||
<div class="mailpoet_automated_latest_content_block_overlay"></div>
|
||||
<div class="mailpoet_automated_latest_content_block_posts"></div>
|
||||
<div class="mailpoet_automated_latest_content_block_overlay"></div>
|
||||
<div class="mailpoet_automated_latest_content_block_posts"></div>
|
||||
</div>
|
||||
<div class="mailpoet_block_highlight"></div>
|
||||
|
@ -215,7 +215,7 @@
|
||||
<%= __('Below text') %>
|
||||
</label>
|
||||
</div>
|
||||
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Categories:') %></div>
|
||||
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Preceded by:') %></div>
|
||||
<div class="mailpoet_form_field_input_option">
|
||||
<input type="text" class="mailpoet_input mailpoet_input_medium mailpoet_automated_latest_content_categories" value="{{ model.categoriesPrecededBy }}" />
|
||||
</div>
|
||||
|
@ -20,6 +20,7 @@
|
||||
{{/ifCond}}
|
||||
|
||||
<div class="mailpoet_form_field">
|
||||
<div class="mailpoet_form_field_title"><%= __('Alignment') %></div>
|
||||
<div class="mailpoet_form_field_radio_option">
|
||||
<label>
|
||||
<input type="radio" name="alignment" class="mailpoet_field_button_alignment" value="left" {{#ifCond model.styles.block.textAlign '===' 'left'}}CHECKED{{/ifCond}}/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="mailpoet_tools"></div>
|
||||
<div class="mailpoet_content">
|
||||
<%= __('Your posts will be inserted here') %>
|
||||
<div class="mailpoet_posts_block_posts"></div>
|
||||
</div>
|
||||
<div class="mailpoet_block_highlight"></div>
|
||||
|
@ -170,7 +170,7 @@
|
||||
<%= __('Below text') %>
|
||||
</label>
|
||||
</div>
|
||||
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Categories:') %></div>
|
||||
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Preceded by:') %></div>
|
||||
<div class="mailpoet_form_field_input_option">
|
||||
<input type="text" class="mailpoet_input mailpoet_input_medium mailpoet_posts_categories" value="{{ model.categoriesPrecededBy }}" />
|
||||
</div>
|
||||
|
@ -13,6 +13,9 @@
|
||||
<option value="pending"><%= __('Pending Review') %></option>
|
||||
<option value="private"><%= __('Private') %></option>
|
||||
</select></div>
|
||||
<div class="mailpoet_post_selection_filter_row">
|
||||
<div class="mailpoet_form_field_title"><%= __('Categories & tags:') %></div>
|
||||
</div>
|
||||
<div class="mailpoet_post_selection_filter_row">
|
||||
<select class="mailpoet_select mailpoet_posts_categories_and_tags" multiple="multiple">
|
||||
{{#each terms}}
|
||||
|
Reference in New Issue
Block a user