Merge pull request #275 from mailpoet/newsletter_template

Newsletter template preview
This commit is contained in:
Marco
2015-12-18 14:54:21 +01:00
16 changed files with 85 additions and 58 deletions

View File

@@ -101,3 +101,6 @@
[data-type="standard"] .mailpoet_thumbnail
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%220%200%2070%2070%22%20enable-background%3D%22new%200%200%2070%2070%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpath%20fill%3D%22%23ffffff%22%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M62.751%2C65.368L43.923%2C50.955l18.832-14.377l-5.395-4.118v-3.479l5.983%2C4.568%20v3.479l0.166%2C26.269C63.51%2C64.089%2C63.198%2C64.783%2C62.751%2C65.368z%20M31.433%2C49.5l-15.955-12v-30c0-1.657%2C1.339-3%2C2.992-3h33.905%20c1.652%2C0%2C2.992%2C1.343%2C2.992%2C3v30l-15.955%2C12H31.433z%20M18.469%2C35.5H33.5v-2H18.469V35.5z%20M18.469%2C31.5H33.5v-2H18.469V31.5z%20M18.469%2C27.5H33.5v-2H18.469V27.5z%20M38.406%2C7.5H18.469v14h19.937V7.5z%20M52.375%2C7.5H40.408v2h11.967V7.5z%20M52.375%2C11.5H40.408v2%20h11.967V11.5z%20M52.375%2C15.5H40.408v2h11.967V15.5z%20M52.375%2C19.5H40.408v2h11.967V19.5z%20M52.375%2C25.5H37.5v2h14.875V25.5z%20M52.375%2C29.5H37.5v2h14.875V29.5z%20M52.375%2C33.5H37.5v2h14.875V33.5z%20M26.14%2C17.192L28.442%2C9.5l3.277%2C6.571l1.71-2.571l2.992%2C6%20h-2.992h-3.989h-0.997H25.45h-4.986l3.989-4L26.14%2C17.192z%20M22.469%2C12.5h-1c-0.552%2C0-1-0.448-1-1v-1c0-0.552%2C0.448-1%2C1-1h1%20c0.552%2C0%2C1%2C0.448%2C1%2C1v1C23.469%2C12.052%2C23.021%2C12.5%2C22.469%2C12.5z%20M26.795%2C50.955L8.05%2C65.305c-0.419-0.574-0.55-1.41-0.55-2.174%20V37.015l-0.015%2C0.011v-3.479l5.998-4.579v3.479L8.017%2C36.62L26.795%2C50.955z%20M29.137%2C52.659v-0.157h12.462v0.144l0.047-0.036%20L59.73%2C66.5H10.989l18.084-13.889L29.137%2C52.659z%22%2F%3E%3C%2Fsvg%3E%0A")
.mailpoet_boxes_preview
margin: -10px
padding: 10px 20px

View File

@@ -11,10 +11,10 @@ define([
'newsletter_editor/blocks/base',
'newsletter_editor/blocks/button',
'newsletter_editor/blocks/divider',
'newsletter_editor/components/wordpress',
'newsletter_editor/components/communication',
'underscore',
'jquery'
], function(App, BaseBlock, ButtonBlock, DividerBlock, WordpressComponent, _, jQuery) {
], function(App, BaseBlock, ButtonBlock, DividerBlock, CommunicationComponent, _, jQuery) {
"use strict";
@@ -69,7 +69,7 @@ define([
},
fetchPosts: function() {
var that = this;
WordpressComponent.getTransformedPosts(this.toJSON()).done(function(content) {
CommunicationComponent.getTransformedPosts(this.toJSON()).done(function(content) {
console.log('ALC fetched', arguments);
that.get('_container').get('blocks').reset(content, {parse: true});
}).fail(function(error) {
@@ -161,7 +161,7 @@ define([
var that = this;
// Dynamically update available post types
WordpressComponent.getPostTypes().done(_.bind(this._updateContentTypes, this));
CommunicationComponent.getPostTypes().done(_.bind(this._updateContentTypes, this));
this.$('.mailpoet_automated_latest_content_categories_and_tags').select2({
multiple: true,
@@ -174,10 +174,10 @@ define([
},
transport: function(options, success, failure) {
var taxonomies,
promise = WordpressComponent.getTaxonomies(that.model.get('contentType')).then(function(tax) {
promise = CommunicationComponent.getTaxonomies(that.model.get('contentType')).then(function(tax) {
taxonomies = tax;
// Fetch available terms based on the list of taxonomies already fetched
var promise = WordpressComponent.getTerms({
var promise = CommunicationComponent.getTerms({
search: options.data.term,
taxonomies: _.keys(taxonomies)
}).then(function(terms) {

View File

@@ -18,12 +18,12 @@ define([
'jquery',
'mailpoet',
'newsletter_editor/App',
'newsletter_editor/components/wordpress',
'newsletter_editor/components/communication',
'newsletter_editor/blocks/base',
'newsletter_editor/blocks/button',
'newsletter_editor/blocks/divider',
'select2'
], function(Backbone, Marionette, Radio, _, jQuery, MailPoet, App, WordpressComponent, BaseBlock, ButtonBlock, DividerBlock) {
], function(Backbone, Marionette, Radio, _, jQuery, MailPoet, App, CommunicationComponent, BaseBlock, ButtonBlock, DividerBlock) {
"use strict";
@@ -96,7 +96,7 @@ define([
},
fetchAvailablePosts: function() {
var that = this;
WordpressComponent.getPosts(this.toJSON()).done(function(posts) {
CommunicationComponent.getPosts(this.toJSON()).done(function(posts) {
console.log('Posts fetched', arguments);
that.get('_availablePosts').reset(posts);
that.get('_selectedPosts').reset(); // Empty out the collection
@@ -116,7 +116,7 @@ define([
return;
}
WordpressComponent.getTransformedPosts(data).done(function(posts) {
CommunicationComponent.getTransformedPosts(data).done(function(posts) {
console.log('Transformed posts fetched', arguments);
that.get('_transformedPosts').get('blocks').reset(posts, {parse: true});
}).fail(function() {
@@ -133,7 +133,7 @@ define([
if (data.posts.length === 0) return;
WordpressComponent.getTransformedPosts(data).done(function(posts) {
CommunicationComponent.getTransformedPosts(data).done(function(posts) {
console.log('Available posts fetched', arguments);
collection.add(posts, { at: index });
}).fail(function() {
@@ -271,7 +271,7 @@ define([
var that = this;
// Dynamically update available post types
WordpressComponent.getPostTypes().done(_.bind(this._updateContentTypes, this));
CommunicationComponent.getPostTypes().done(_.bind(this._updateContentTypes, this));
this.$('.mailpoet_posts_categories_and_tags').select2({
multiple: true,
@@ -284,10 +284,10 @@ define([
},
transport: function(options, success, failure) {
var taxonomies,
promise = WordpressComponent.getTaxonomies(that.model.get('contentType')).then(function(tax) {
promise = CommunicationComponent.getTaxonomies(that.model.get('contentType')).then(function(tax) {
taxonomies = tax;
// Fetch available terms based on the list of taxonomies already fetched
var promise = WordpressComponent.getTerms({
var promise = CommunicationComponent.getTerms({
search: options.data.term,
taxonomies: _.keys(taxonomies)
}).then(function(terms) {

View File

@@ -70,9 +70,10 @@ define([
};
Module.previewNewsletter = function(options) {
return Module._query({
return MailPoet.Ajax.post({
endpoint: 'newsletters',
action: 'preview',
options: options,
data: options || {},
});
};

View File

@@ -44,10 +44,10 @@ define([
};
Module.getBody = function() {
return JSON.stringify({
return {
content: App._contentContainer.toJSON(),
globalStyles: App.getGlobalStyles().toJSON(),
});
};
};
Module.toJSON = function() {
@@ -73,8 +73,7 @@ define([
});
App.on('start', function(options) {
// TODO: Other newsletter information will be needed as well.
var body = JSON.parse(options.newsletter.body);
var body = options.newsletter.body;
App._contentContainer = new (App.getBlockTypeModel('container'))(body.content, {parse: true});
App._contentContainerView = new (App.getBlockTypeView('container'))({
model: App._contentContainer,

View File

@@ -1,12 +1,13 @@
define([
'newsletter_editor/App',
'newsletter_editor/components/communication',
'backbone',
'backbone.marionette',
'backbone.supermodel',
'underscore',
'jquery',
'sticky-kit'
], function(App, Backbone, Marionette, SuperModel, _, jQuery, StickyKit) {
], function(App, CommunicationComponent, Backbone, Marionette, SuperModel, _, jQuery, StickyKit) {
"use strict";
@@ -229,7 +230,7 @@ define([
MailPoet.Modal.loading(true);
// TODO: Migrate logic to new AJAX format
Wordpress.previewNewsletter(data).done(function(response) {
CommunicationComponent.previewNewsletter(data).done(function(response) {
if(response.success !== undefined && response.success === true) {
MailPoet.Notice.success(App.getConfig().get('translations.testEmailSent'));
} else if(response.error !== undefined) {

View File

@@ -72,7 +72,7 @@ define([
App.getAvailableStyles = Module.getAvailableStyles;
var body = JSON.parse(options.newsletter.body);
var body = options.newsletter.body;
this.setGlobalStyles(body.globalStyles);
});

View File

@@ -153,7 +153,7 @@ define(
handleShowTemplate: function(template) {
MailPoet.Modal.popup({
title: template.name,
template: '<img src="{{ thumbnail }}" />',
template: '<div class="mailpoet_boxes_preview" style="background-color: {{ body.globalStyles.body.backgroundColor }}"><img src="{{ thumbnail }}" /></div>',
data: template,
});
},

View File

@@ -15,16 +15,25 @@ class NewsletterTemplates {
if($template === false) {
wp_send_json(false);
} else {
$template->body = json_decode($template->body);
wp_send_json($template->asArray());
}
}
function getAll() {
$collection = NewsletterTemplate::findArray();
$collection = array_map(function($item) {
$item['body'] = json_decode($item['body']);
return $item;
}, $collection);
wp_send_json($collection);
}
function save($data = array()) {
if (isset($data['body'])) {
$data['body'] = json_encode($data['body']);
}
$result = NewsletterTemplate::createOrUpdate($data);
if($result !== true) {
wp_send_json($result);

View File

@@ -33,6 +33,7 @@ class Newsletters {
return $segment['id'];
}, $segments);
$newsletter['options'] = $options;
$newsletter['body'] = json_decode($newsletter['body']);
wp_send_json($newsletter);
}
@@ -40,6 +41,10 @@ class Newsletters {
function getAll() {
$collection = Newsletter::findArray();
$collection = array_map(function($item) {
$item['body'] = json_decode($item['body']);
return $item;
}, $collection);
wp_send_json($collection);
}
@@ -54,6 +59,10 @@ class Newsletters {
unset($data['options']);
}
if (isset($data['body'])) {
$data['body'] = json_encode($data['body']);
}
$errors = array();
$result = false;
@@ -282,6 +291,7 @@ class Newsletters {
}
}
}
$newsletter->body = json_decode($newsletter->body);
wp_send_json($newsletter->asArray());
}
}

View File

@@ -2,8 +2,8 @@ define([
'newsletter_editor/App',
'newsletter_editor/blocks/automatedLatestContent',
'amd-inject-loader!newsletter_editor/blocks/automatedLatestContent',
'newsletter_editor/components/wordpress',
], function(EditorApplication, AutomatedLatestContentBlock, AutomatedLatestContentInjector, WordpressComponent) {
'newsletter_editor/components/communication',
], function(EditorApplication, AutomatedLatestContentBlock, AutomatedLatestContentInjector, CommunicationComponent) {
describe('Automated latest content', function () {
describe('model', function () {
@@ -11,7 +11,7 @@ define([
before(function() {
module = AutomatedLatestContentInjector({
'newsletter_editor/components/wordpress': {
'newsletter_editor/components/communication': {
getTransformedPosts: function() {
return jQuery.Deferred();
}
@@ -199,7 +199,7 @@ define([
before(function() {
module = AutomatedLatestContentInjector({
'newsletter_editor/components/wordpress': {
'newsletter_editor/components/communication': {
getTransformedPosts: function() {
return jQuery.Deferred();
}
@@ -231,7 +231,7 @@ define([
before(function() {
module = AutomatedLatestContentInjector({
'newsletter_editor/components/wordpress': {
'newsletter_editor/components/communication': {
getTransformedPosts: function() {
return jQuery.Deferred();
},
@@ -243,7 +243,7 @@ define([
});
before(function () {
WordpressComponent.getPostTypes = function() {
CommunicationComponent.getPostTypes = function() {
var deferred = jQuery.Deferred();
deferred.resolve([
{

View File

@@ -1,8 +1,8 @@
define([
'newsletter_editor/App',
'newsletter_editor/components/wordpress',
'newsletter_editor/components/communication',
'newsletter_editor/blocks/posts'
], function(EditorApplication, WordpressComponent, PostsBlock) {
], function(EditorApplication, CommunicationComponent, PostsBlock) {
describe('Posts', function () {
Backbone.Radio = {
@@ -16,7 +16,7 @@ define([
var model;
before(function() {
WordpressComponent.getPosts = function() {
CommunicationComponent.getPosts = function() {
var deferred = jQuery.Deferred();
return deferred;
};
@@ -226,7 +226,7 @@ define([
var model, view;
before(function () {
WordpressComponent.getPostTypes = function() {
CommunicationComponent.getPostTypes = function() {
var deferred = jQuery.Deferred();
deferred.resolve([
{

View File

@@ -1,12 +1,12 @@
define([
'newsletter_editor/App',
'newsletter_editor/components/wordpress',
'amd-inject-loader!newsletter_editor/components/wordpress'
], function(EditorApplication, Wordpress, WordpressInjector) {
'newsletter_editor/components/communication',
'amd-inject-loader!newsletter_editor/components/communication'
], function(EditorApplication, Communication, CommunicationInjector) {
describe('getPostTypes', function() {
it('fetches post types from the server', function() {
var module = WordpressInjector({
var module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: function() {
@@ -28,7 +28,7 @@ define([
it('caches results', function() {
var deferred = jQuery.Deferred(),
mock = sinon.mock({ post: function() {} }).expects('post').once().returns(deferred),
module = WordpressInjector({
module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: mock,
@@ -59,7 +59,7 @@ define([
},
module;
spy = sinon.spy(post);
module = WordpressInjector({
module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: spy,
@@ -72,7 +72,7 @@ define([
});
it('fetches post types from the server', function() {
var module = WordpressInjector({
var module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: function() {
@@ -91,7 +91,7 @@ define([
it('caches results', function() {
var deferred = jQuery.Deferred(),
mock = sinon.mock({ post: function() {} }).expects('post').once().returns(deferred),
module = WordpressInjector({
module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: mock,
@@ -116,7 +116,7 @@ define([
},
module;
spy = sinon.spy(post);
module = WordpressInjector({
module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: spy,
@@ -131,7 +131,7 @@ define([
});
it('fetches terms from the server', function() {
var module = WordpressInjector({
var module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: function() {
@@ -150,7 +150,7 @@ define([
it('caches results', function() {
var deferred = jQuery.Deferred(),
mock = sinon.mock({ post: function() {} }).expects('post').once().returns(deferred),
module = WordpressInjector({
module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: mock,
@@ -175,7 +175,7 @@ define([
},
module;
spy = sinon.spy(post);
module = WordpressInjector({
module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: spy,
@@ -194,7 +194,7 @@ define([
});
it('fetches posts from the server', function() {
var module = WordpressInjector({
var module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: function() {
@@ -213,7 +213,7 @@ define([
it('caches results', function() {
var deferred = jQuery.Deferred(),
mock = sinon.mock({ post: function() {} }).expects('post').once().returns(deferred),
module = WordpressInjector({
module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: mock,
@@ -241,7 +241,7 @@ define([
},
module;
spy = sinon.spy(post);
module = WordpressInjector({
module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: spy,
@@ -260,7 +260,7 @@ define([
});
it('fetches transformed posts from the server', function() {
var module = WordpressInjector({
var module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: function() {
@@ -279,7 +279,7 @@ define([
it('caches results', function() {
var deferred = jQuery.Deferred(),
mock = sinon.mock({ post: function() {} }).expects('post').once().returns(deferred),
module = WordpressInjector({
module = CommunicationInjector({
"mailpoet": {
Ajax: {
post: mock,

View File

@@ -81,10 +81,10 @@ define([
};
var json = ContentComponent.toJSON();
expect(json).to.deep.equal(_.extend({
body: JSON.stringify({
body: {
content: dataField,
globalStyles: stylesField
}),
},
}, newsletterFields));
});
});

View File

@@ -95,7 +95,7 @@ define([
expect(view.$('.mailpoet_save_options')).to.not.have.$class('mailpoet_hidden');
});
it('triggers template saving when clicked on save as template button', function() {
it('triggers template saving when clicked on "save as template" button', function() {
var mock = sinon.mock({ post: function() {} }).expects('post').once().returns(jQuery.Deferred()),
html2canvasMock = jQuery.Deferred();
@@ -108,7 +108,11 @@ define([
'mailpoet': {
Ajax: {
post: mock,
}
},
Notice: {
success: function() {},
error: function() {},
},
},
'newsletter_editor/App': EditorApplication,
'html2canvas': function() { return html2canvasMock; },

View File

@@ -132,7 +132,7 @@ config.push(_.extend({}, baseConfig, {
'newsletter_editor/components/content.js',
'newsletter_editor/components/heading.js',
'newsletter_editor/components/save.js',
'newsletter_editor/components/wordpress.js',
'newsletter_editor/components/communication.js',
'newsletter_editor/behaviors/BehaviorsLookup.js',
'newsletter_editor/behaviors/ColorPickerBehavior.js',
'newsletter_editor/behaviors/ContainerDropZoneBehavior.js',
@@ -201,7 +201,7 @@ config.push(_.extend({}, baseConfig, {
'newsletter_editor/components/content.js',
'newsletter_editor/components/heading.js',
'newsletter_editor/components/save.js',
'newsletter_editor/components/wordpress.js',
'newsletter_editor/components/communication.js',
'newsletter_editor/behaviors/BehaviorsLookup.js',
'newsletter_editor/behaviors/ColorPickerBehavior.js',
'newsletter_editor/behaviors/ContainerDropZoneBehavior.js',
@@ -227,7 +227,7 @@ config.push(_.extend({}, baseConfig, {
'components/save.spec.js',
'components/sidebar.spec.js',
'components/styles.spec.js',
'components/wordpress.spec.js',
'components/communication.spec.js',
'blocks/automatedLatestContent.spec.js',
'blocks/button.spec.js',