6 changed files with 308 additions and 3 deletions
@ -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": { |
|||
} |
|||
} |
|||
] |
|||
} |
|||
@ -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, |
|||
}); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue