Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.
Header Level 2
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam tincidunt mauris eu risus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.
Header Level 3
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
'),
published_at: new Date('2015-01-01'),
custom_excerpt: 'This is my custom excerpt!',
feature_image: 'https://example.com/super_photo.jpg'
},
{
id: ObjectId.generate(),
title: 'Ghostly Kitchen Sink',
slug: 'ghostly-kitchen-sink',
mobiledoc: DataGenerator.markdownToMobiledoc('
HTML Ipsum Presents
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.
Header Level 2
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam tincidunt mauris eu risus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.
Header Level 3
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.
Header Level 2
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam tincidunt mauris eu risus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.
Header Level 3
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
'),
status: 'draft',
uuid: 'd52c42ae-2755-455c-80ec-70b2ec55c903'
},
{
id: ObjectId.generate(),
title: 'Not so short, bit complex',
slug: 'not-so-short-bit-complex',
mobiledoc: DataGenerator.markdownToMobiledoc('
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.
1
2
3
4
a
b
c
d
e
f
g
h
i
j
k
l
Definition list
Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Lorem ipsum dolor sit amet
Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.
Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.
Phasellus ultrices nulla quis nibh. Quisque a lectus. Donec consectetuer ligula vulputate sem tristique cursus. Nam nulla quam, gravida non, commodo a, sodales sit amet, nisi.
Pellentesque fermentum dolor. Aliquam quam lectus, facilisis auctor, ultrices ut, elementum vulputate, nunc.
'),
featured: true
},
{
id: ObjectId.generate(),
title: 'This is a static page',
slug: 'static-page-test',
mobiledoc: DataGenerator.markdownToMobiledoc('
Static page test is what this is for.
Hopefully you don\'t find it a bore.
'),
type: 'page'
},
{
id: ObjectId.generate(),
title: 'This is a draft static page',
slug: 'static-page-draft',
mobiledoc: DataGenerator.markdownToMobiledoc('
Static page test is what this is for.
Hopefully you don\'t find it a bore.
'),
type: 'page',
status: 'draft'
},
{
id: ObjectId.generate(),
title: 'This is a scheduled post!!',
slug: 'scheduled-post',
mobiledoc: DataGenerator.markdownToMobiledoc('
',
plaintext: 'yes this is an email',
track_opens: false,
submitted_at: moment().toDate()
}
],
email_batches: [
{
id: ObjectId.generate(),
email_id: null, // emails[0] relation added later
// TODO: cleanup <> in provider_id
provider_id: '',
status: 'submitted'
}
],
email_recipients: [
{
id: ObjectId.generate(),
email_id: null, // emails[0] relation added later
member_id: null, // members[0] relation added later
batch_id: null, // email_batches[0] relation added later
processed_at: moment().toDate(),
failed_at: null,
member_uuid: 'f6f91461-d7d8-4a3f-aa5d-8e582c40b340',
member_email: 'member1@test.com',
member_name: 'Mr Egg'
},
{
id: ObjectId.generate(),
email_id: null, // emails[0] relation added later
member_id: null, // members[1] relation added later
batch_id: null, // email_batches[0] relation added later
processed_at: moment().toDate(),
failed_at: null,
member_uuid: 'f6f91461-d7d8-4a3f-aa5d-8e582c40b341',
member_email: 'member2@test.com',
member_name: null
},
{
id: ObjectId.generate(),
email_id: null, // emails[0] relation added later
member_id: null, // members[2] relation added later
batch_id: null, // email_batches[0] relation added later
processed_at: moment().toDate(),
failed_at: null,
member_uuid: 'f6f91461-d7d8-4a3f-aa5d-8e582c40b342',
member_email: 'member1@test.com',
member_name: 'Mr Egg'
},
{
id: ObjectId.generate(),
email_id: null, // emails[0] relation added later
member_id: null, // members[3] relation added later
batch_id: null, // email_batches[0] relation added later
processed_at: moment().toDate(),
failed_at: null,
member_uuid: 'f6f91461-d7d8-4a3f-aa5d-8e582c40b343',
member_email: 'member1@test.com',
member_name: 'Mr Egg'
}
],
snippets: [
{
id: ObjectId.generate(),
name: 'Test snippet 1',
mobiledoc: '{}'
}
]
};
// set up belongs_to relationships
DataGenerator.Content.subscribers[0].post_id = DataGenerator.Content.posts[0].id;
DataGenerator.Content.api_keys[0].integration_id = DataGenerator.Content.integrations[0].id;
DataGenerator.Content.api_keys[1].integration_id = DataGenerator.Content.integrations[0].id;
DataGenerator.Content.emails[0].post_id = DataGenerator.Content.posts[0].id;
DataGenerator.Content.emails[1].post_id = DataGenerator.Content.posts[1].id;
DataGenerator.Content.email_batches[0].email_id = DataGenerator.Content.emails[0].id;
DataGenerator.Content.email_recipients[0].batch_id = DataGenerator.Content.email_batches[0].id;
DataGenerator.Content.email_recipients[0].email_id = DataGenerator.Content.email_batches[0].email_id;
DataGenerator.Content.email_recipients[0].member_id = DataGenerator.Content.members[0].id;
DataGenerator.Content.email_recipients[1].batch_id = DataGenerator.Content.email_batches[0].id;
DataGenerator.Content.email_recipients[1].email_id = DataGenerator.Content.email_batches[0].email_id;
DataGenerator.Content.email_recipients[1].member_id = DataGenerator.Content.members[1].id;
DataGenerator.Content.email_recipients[2].batch_id = DataGenerator.Content.email_batches[0].id;
DataGenerator.Content.email_recipients[2].email_id = DataGenerator.Content.email_batches[0].email_id;
DataGenerator.Content.email_recipients[2].member_id = DataGenerator.Content.members[2].id;
DataGenerator.Content.email_recipients[3].batch_id = DataGenerator.Content.email_batches[0].id;
DataGenerator.Content.email_recipients[3].email_id = DataGenerator.Content.email_batches[0].email_id;
DataGenerator.Content.email_recipients[3].member_id = DataGenerator.Content.members[3].id;
DataGenerator.Content.members_stripe_customers[0].member_id = DataGenerator.Content.members[2].id;
DataGenerator.Content.members_stripe_customers[1].member_id = DataGenerator.Content.members[3].id;
DataGenerator.forKnex = (function () {
function createBasic(overrides) {
const newObj = _.cloneDeep(overrides);
return _.defaults(newObj, {
id: ObjectId.generate(),
created_by: DataGenerator.Content.users[0].id,
created_at: new Date(),
updated_by: DataGenerator.Content.users[0].id,
updated_at: new Date()
});
}
function createTag(overrides) {
const newObj = _.cloneDeep(overrides);
return _.defaults(newObj, {
id: ObjectId.generate(),
name: 'tag',
slug: 'slug',
feature_image: null,
meta_title: null,
meta_description: null,
description: 'description',
visibility: 'public',
created_by: DataGenerator.Content.users[0].id,
created_at: new Date(),
updated_by: DataGenerator.Content.users[0].id,
updated_at: new Date()
});
}
function createPost(overrides) {
overrides = overrides || {};
const newObj = _.cloneDeep(overrides);
let mobiledocObj;
if (!newObj.mobiledoc) {
newObj.mobiledoc = DataGenerator.markdownToMobiledoc('## markdown');
}
if (!newObj.html) {
mobiledocObj = JSON.parse(newObj.mobiledoc);
newObj.html = mobiledocObj.cards && mobiledocObj.cards[0][1].markdown;
}
return _.defaults(newObj, {
id: ObjectId.generate(),
uuid: uuid.v4(),
title: 'title',
status: 'published',
feature_image: null,
featured: false,
type: 'post',
slug: 'slug',
author_id: DataGenerator.Content.users[0].id,
updated_at: new Date(),
updated_by: DataGenerator.Content.users[0].id,
created_at: new Date(),
created_by: DataGenerator.Content.users[0].id,
published_at: new Date(),
published_by: DataGenerator.Content.users[0].id,
visibility: 'public'
});
}
function createGenericPost(uniqueInteger, status, locale, author_id) {
status = status || 'draft';
locale = locale || null;
author_id = author_id || DataGenerator.Content.users[0].id;
return createPost({
id: ObjectId.generate(),
title: 'Test Post ' + uniqueInteger,
slug: 'ghost-from-fiction-to-function-' + uniqueInteger,
author_id: author_id,
mobiledoc: DataGenerator.markdownToMobiledoc('Three days ago I released a concept page<\/a> for a lite version of WordPress that I\'ve been thinking about for a long time, called Ghost. I think it\'s fair to say that I didn\'t quite anticipate how strong the reaction would be - and I\'ve hardly had time to catch my breath in the last 72 hours.\n\nThe response was overwhelming, and overwhelmingly positive. In the first 6 hours my site got 35,000 page views after hitting the number 1 slot on Hacker News<\/a>. As of right now, the traffic count is just over 91,000 page views<\/a> - and Ghost has been featured all over the place. Notable mentions so far include Christina Warren from Mashable, who wrote about it<\/a>. Michael Carney from PandoDaily interviewed me about it<\/a>. Someone even wrote about it in Chinese<\/a>. That\'s pretty cool.\n\n\nThe feedback has been amazing, and while it\'s impossible to reply to all of the messages individually, I\'m getting to as many of them as I can and I want to thank each and every one of you who took the time to send me a message or share the concept because you liked it. Now that the initial storm has died down a bit, I wanted to take some time to answer some of the more common questions and talk about what\'s next.\n