Add block.json file support + fields config.
This commit is contained in:
@@ -14,3 +14,4 @@ config
|
|||||||
data
|
data
|
||||||
src
|
src
|
||||||
exports
|
exports
|
||||||
|
block.json
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
import {exec} from 'child_process';
|
import {exec} from 'child_process';
|
||||||
import config from 'config';
|
import config from 'config';
|
||||||
import Generator from "yeoman-generator";
|
import Generator from "yeoman-generator";
|
||||||
|
import yeoman from 'yeoman-environment';
|
||||||
|
import {buildHubspot} from "./platforms/hubspot/hubspot-adapter.js";
|
||||||
|
|
||||||
const isDev = process.env.NODE_ENV === 'development' || (config.has('isDev') && config.get('isDev')); // Check README file in case you get "missing files" error.
|
const isDev = process.env.NODE_ENV === 'development' || (config.has('isDev') && config.get('isDev')); // Check README file in case you get "missing files" error.
|
||||||
const modulePath = isDev ? '' : 'node_modules/create-block-dev-tool/';
|
const modulePath = isDev ? '' : 'node_modules/create-block-dev-tool/';
|
||||||
@@ -30,8 +32,13 @@ class buildGenerator extends Generator {
|
|||||||
console.log(stdout);
|
console.log(stdout);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
} else if (this.data.platform === 'Hubspot Email') {
|
||||||
|
buildHubspot(blockName)
|
||||||
|
.then(() => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
} else if (this.data.platform === 'Hubspot') {
|
} else if (this.data.platform === 'Hubspot') {
|
||||||
console.log('Coming soon...');
|
console.log('"Hubspot" Coming soon...');
|
||||||
resolve();
|
resolve();
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
@@ -43,7 +50,6 @@ class buildGenerator extends Generator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import yeoman from 'yeoman-environment';
|
|
||||||
|
|
||||||
const build = new buildGenerator([], {env: yeoman.createEnv()}, {});
|
const build = new buildGenerator([], {env: yeoman.createEnv()}, {});
|
||||||
build.run().then(() => null);
|
build.run().then(() => null);
|
||||||
|
|||||||
@@ -21,6 +21,20 @@ module.exports = class extends Generator {
|
|||||||
return !!str;
|
return !!str;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "input",
|
||||||
|
name: "group",
|
||||||
|
message: "Company/Organization Name",
|
||||||
|
validate: (str) => {
|
||||||
|
const matches = str.match(/\d+/g);
|
||||||
|
|
||||||
|
if (matches != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!str;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
name: "baseView",
|
name: "baseView",
|
||||||
@@ -45,9 +59,11 @@ module.exports = class extends Generator {
|
|||||||
|
|
||||||
writing() {
|
writing() {
|
||||||
const title = capitalize(this.data.name);
|
const title = capitalize(this.data.name);
|
||||||
|
const group = capitalize(this.data.group);
|
||||||
const data = Object.assign(this.data, {
|
const data = Object.assign(this.data, {
|
||||||
title,
|
title,
|
||||||
blockFilename: title.toLowerCase().replace(/ /ig, '-'),
|
blockFilename: title.toLowerCase().replace(/ /ig, '-'),
|
||||||
|
blockGroupName: group.toLowerCase().replace(/ /ig, '-'),
|
||||||
blockClassName: title.toLowerCase().replace(/ /ig, '_'),
|
blockClassName: title.toLowerCase().replace(/ /ig, '_'),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -85,6 +101,12 @@ module.exports = class extends Generator {
|
|||||||
data
|
data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.fs.copyTpl(
|
||||||
|
this.templatePath('block.json'),
|
||||||
|
this.destinationPath(path.join(pathDist, 'block.json')),
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|
||||||
this.fs.copyTpl(
|
this.fs.copyTpl(
|
||||||
this.templatePath('package.json'),
|
this.templatePath('package.json'),
|
||||||
this.destinationPath(path.join(pathDist, 'package.json')),
|
this.destinationPath(path.join(pathDist, 'package.json')),
|
||||||
@@ -123,7 +145,8 @@ module.exports = class extends Generator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function capitalize(str) {
|
// TODO: Same function is located in "/helpers.js" file. Find a way to remove cjs files.
|
||||||
|
export function capitalize(str) {
|
||||||
if (typeof str !== 'string') {
|
if (typeof str !== 'string') {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "<%= blockGroupName %>/<%= blockFilename %>",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"title": "<%= title %>",
|
||||||
|
"categories": [],
|
||||||
|
"icon": "shortcode",
|
||||||
|
"preview_image": "",
|
||||||
|
"field_groups": [
|
||||||
|
{
|
||||||
|
"name": "content",
|
||||||
|
"label": "Content",
|
||||||
|
"fields": {
|
||||||
|
"title": {
|
||||||
|
"type": "text",
|
||||||
|
"label": "Title"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "wysiwyg",
|
||||||
|
"label": "Content"
|
||||||
|
},
|
||||||
|
"cta": {
|
||||||
|
"type": "link",
|
||||||
|
"label": "CTA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "styling",
|
||||||
|
"label": "Styling",
|
||||||
|
"fields": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// TODO: Same function is located in "/generators/block/index.cjs" file. Find a way to remove cjs files.
|
||||||
|
export function capitalize(str) {
|
||||||
|
if (typeof str !== 'string') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return str
|
||||||
|
.toLowerCase()
|
||||||
|
.split(/[ -_]/g)
|
||||||
|
.filter((word) => !!word)
|
||||||
|
.map((word) => {
|
||||||
|
return word.charAt(0).toUpperCase() + word.slice(1);
|
||||||
|
})
|
||||||
|
.join(' ');
|
||||||
|
}
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
import {readFile, writeFile, mkdir, copyFile} from "fs/promises";
|
||||||
|
import {capitalize} from "../../helpers.js";
|
||||||
|
|
||||||
|
export async function buildHubspot(blockName) {
|
||||||
|
const distPath = `./exports/hubspot/${blockName}.module`;
|
||||||
|
await mkdir(distPath, {recursive: true})
|
||||||
|
await copyFile(`./src/${blockName}.template.hbs`, `${distPath}/module.html`)
|
||||||
|
|
||||||
|
const metaData = {
|
||||||
|
global: false,
|
||||||
|
host_template_types: ["EMAIL"],
|
||||||
|
label: capitalize(blockName),
|
||||||
|
is_available_for_new_content: true
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeFile(`${distPath}/meta.json`, JSON.stringify(metaData, null, 4));
|
||||||
|
|
||||||
|
const blockJSON = await readFile(`./block.json`, "utf8");
|
||||||
|
const block = JSON.parse(blockJSON);
|
||||||
|
|
||||||
|
const fields = getBlockFields(block, 'content');
|
||||||
|
|
||||||
|
// Styling TAB.
|
||||||
|
const stylingFields = getBlockFields(block, 'styling');
|
||||||
|
|
||||||
|
if (stylingFields.length) {
|
||||||
|
const stylingFieldsByName = {};
|
||||||
|
stylingFields.forEach(field => stylingFieldsByName[field.name] = field);
|
||||||
|
|
||||||
|
const stylingGroup = convertToHubspotField({
|
||||||
|
type: 'group',
|
||||||
|
name: 'style',
|
||||||
|
label: "Style",
|
||||||
|
sub_fields: stylingFieldsByName,
|
||||||
|
});
|
||||||
|
stylingGroup.tab = "STYLE";
|
||||||
|
|
||||||
|
fields.push(stylingGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export JSON file.
|
||||||
|
await writeFile(`${distPath}/fields.json`, JSON.stringify(fields, null, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBlockFields(block = {}, type = 'content') {
|
||||||
|
const fields_group = block['field_groups'].find((group) => group.name === type);
|
||||||
|
const fields = [];
|
||||||
|
|
||||||
|
if (!fields_group) {
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(fields_group['fields']).forEach((key) => {
|
||||||
|
const field = fields_group['fields'][key];
|
||||||
|
field['name'] = key;
|
||||||
|
|
||||||
|
fields.push(field);
|
||||||
|
});
|
||||||
|
|
||||||
|
return fields.map((field) => {
|
||||||
|
return convertToHubspotField(field);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertToHubspotField(field = {}) {
|
||||||
|
const data = {
|
||||||
|
id: field.name,
|
||||||
|
name: field.name,
|
||||||
|
label: field.label,
|
||||||
|
display_width: null,
|
||||||
|
validation_regex: "",
|
||||||
|
required: false,
|
||||||
|
locked: false,
|
||||||
|
default: field.default
|
||||||
|
};
|
||||||
|
|
||||||
|
let sub_fields = [];
|
||||||
|
|
||||||
|
switch (field.type) {
|
||||||
|
case 'text':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "text",
|
||||||
|
allow_new_line: true,
|
||||||
|
show_emoji_picker: false,
|
||||||
|
});
|
||||||
|
case 'wysiwyg':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "richtext"
|
||||||
|
});
|
||||||
|
case 'number':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "number",
|
||||||
|
display: "text",
|
||||||
|
step: 1,
|
||||||
|
});
|
||||||
|
case 'range':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "number",
|
||||||
|
display: "slider",
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 3,
|
||||||
|
});
|
||||||
|
case 'boolean':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "boolean",
|
||||||
|
display: "toggle",
|
||||||
|
});
|
||||||
|
case 'checkbox':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "boolean",
|
||||||
|
display: "checkbox",
|
||||||
|
});
|
||||||
|
case 'select':
|
||||||
|
const choices = [];
|
||||||
|
Object.keys(data.choices).forEach(value => choices.push([value, data.choices[value]]));
|
||||||
|
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "select",
|
||||||
|
choices: [choices]
|
||||||
|
});
|
||||||
|
case 'link':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "url",
|
||||||
|
supported_types: [
|
||||||
|
"EXTERNAL"
|
||||||
|
],
|
||||||
|
default: {
|
||||||
|
content_id: null,
|
||||||
|
href: "https://www.twitter.com/...",
|
||||||
|
type: "EXTERNAL"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
case 'image':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "image",
|
||||||
|
responsive: true,
|
||||||
|
resizable: false,
|
||||||
|
show_loading: false,
|
||||||
|
default: {
|
||||||
|
src: "",
|
||||||
|
alt: null,
|
||||||
|
loading: "lazy"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
case 'file':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "file",
|
||||||
|
picker: "file",
|
||||||
|
});
|
||||||
|
case 'stringList':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "text",
|
||||||
|
occurrence: {
|
||||||
|
min: null,
|
||||||
|
max: null,
|
||||||
|
sorting_label_field: null,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
allow_new_line: false,
|
||||||
|
show_emoji_picker: false,
|
||||||
|
});
|
||||||
|
case 'gallery':
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "image",
|
||||||
|
occurrence: {
|
||||||
|
min: null,
|
||||||
|
max: null,
|
||||||
|
sorting_label_field: null,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
responsive: true,
|
||||||
|
resizable: false,
|
||||||
|
show_loading: false,
|
||||||
|
default: {
|
||||||
|
src: "",
|
||||||
|
alt: null,
|
||||||
|
loading: "lazy"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
case 'group':
|
||||||
|
field.sub_fields = field.sub_fields || {};
|
||||||
|
sub_fields = Object.keys(field.sub_fields).map(name => {
|
||||||
|
const sub_field = Object.assign({}, field.sub_fields[name], {name: `${field.name}_${name}`});
|
||||||
|
return convertToHubspotField(sub_field);
|
||||||
|
})
|
||||||
|
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "group",
|
||||||
|
children: sub_fields,
|
||||||
|
tab: "CONTENT",
|
||||||
|
expanded: false,
|
||||||
|
default: {}
|
||||||
|
});
|
||||||
|
case 'repeater':
|
||||||
|
field.sub_fields = field.sub_fields || {};
|
||||||
|
sub_fields = Object.keys(field.sub_fields).map(name => {
|
||||||
|
const sub_field = Object.assign({}, field.sub_fields[name], {name: `${field.name}_${name}`});
|
||||||
|
return convertToHubspotField(sub_field);
|
||||||
|
})
|
||||||
|
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "group",
|
||||||
|
children: sub_fields,
|
||||||
|
occurrence: {
|
||||||
|
min: null,
|
||||||
|
max: null,
|
||||||
|
sorting_label_field: null,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
tab: "CONTENT",
|
||||||
|
expanded: false,
|
||||||
|
default: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// case 'YOUR_FIELD':
|
||||||
|
// return Object.assign({}, data, {});
|
||||||
|
default:
|
||||||
|
// type === 'string'
|
||||||
|
return Object.assign({}, data, {
|
||||||
|
type: "text",
|
||||||
|
allow_new_line: false,
|
||||||
|
show_emoji_picker: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user