From 52109f50108ef54b0686aa3071ad8d63876a43fc Mon Sep 17 00:00:00 2001 From: Roman Axelrod Date: Wed, 16 Nov 2022 22:12:02 +0200 Subject: [PATCH 1/4] Support Hubspot pages. --- build.js | 7 ++- ...ot-adapter.js => hubspot-email-adapter.js} | 44 ++++++--------- platforms/hubspot/hubspot-page-adapter.js | 56 +++++++++++++++++++ platforms/wordpress/wordpress-adapter.js | 3 +- 4 files changed, 79 insertions(+), 31 deletions(-) rename platforms/hubspot/{hubspot-adapter.js => hubspot-email-adapter.js} (86%) create mode 100644 platforms/hubspot/hubspot-page-adapter.js diff --git a/build.js b/build.js index 412b538..51e265a 100755 --- a/build.js +++ b/build.js @@ -3,9 +3,10 @@ import config from 'config'; import prompts from "prompts"; -import {buildHubspot} from "./platforms/hubspot/hubspot-adapter.js"; +import {buildHubspotEmail} from "./platforms/hubspot/hubspot-email-adapter.js"; import {getConfigs} from "./helpers.js"; import {buildWordPress} from "./platforms/wordpress/wordpress-adapter.js"; +import {buildHubspotPage} from "./platforms/hubspot/hubspot-page-adapter.js"; const {isDev, developmentBlockName} = getConfigs(); const blockName = !isDev && config.has('blockName') ? config.get('blockName') : developmentBlockName; @@ -51,9 +52,9 @@ export async function buildExportFiles(platform) { } } } else if (platform.name === 'hubspot-email') { - await buildHubspot(blockName) + await buildHubspotEmail(blockName) } else if (platform.name === 'hubspot') { - console.log('"Hubspot" Coming soon...'); + await buildHubspotPage(blockName) } } diff --git a/platforms/hubspot/hubspot-adapter.js b/platforms/hubspot/hubspot-email-adapter.js similarity index 86% rename from platforms/hubspot/hubspot-adapter.js rename to platforms/hubspot/hubspot-email-adapter.js index 27375bd..9646851 100644 --- a/platforms/hubspot/hubspot-adapter.js +++ b/platforms/hubspot/hubspot-email-adapter.js @@ -1,9 +1,12 @@ import {readFile, writeFile, mkdir, copyFile} from "fs/promises"; +import {capitalize, getConfigs} from "../../helpers.js"; -export async function buildHubspot(blockName) { +const {modulesPath, projectPath} = getConfigs(); + +export async function buildHubspotEmail(blockName) { const distPath = `./exports/hubspot/${blockName}.module`; await mkdir(distPath, {recursive: true}) - await copyFile(`./src/${blockName}.template.hbs`, `${distPath}/module.html`) + await copyFile(`${projectPath}/src/${blockName}.template.hbs`, `${distPath}/module.html`) const metaData = { global: false, @@ -14,7 +17,7 @@ export async function buildHubspot(blockName) { await writeFile(`${distPath}/meta.json`, JSON.stringify(metaData, null, 4)); - const blockJSON = await readFile(`./block.json`, "utf8"); + const blockJSON = await readFile(`${projectPath}/block.json`, "utf8"); const block = JSON.parse(blockJSON); const fields = getBlockFields(block, 'content'); @@ -30,8 +33,9 @@ export async function buildHubspot(blockName) { type: 'group', name: 'style', label: "Style", - sub_fields: stylingFieldsByName, }); + + stylingGroup.children = Object.values(stylingFieldsByName); stylingGroup.tab = "STYLE"; fields.push(stylingGroup); @@ -41,7 +45,7 @@ export async function buildHubspot(blockName) { await writeFile(`${distPath}/fields.json`, JSON.stringify(fields, null, 4)); } -function getBlockFields(block = {}, type = 'content') { +export function getBlockFields(block = {}, type = 'content') { const fields_group = block['field_groups'].find((group) => group.name === type); const fields = []; @@ -61,7 +65,7 @@ function getBlockFields(block = {}, type = 'content') { }); } -function convertToHubspotField(field = {}) { +export function convertToHubspotField(field = {}) { const data = { id: field.name, name: field.name, @@ -70,9 +74,12 @@ function convertToHubspotField(field = {}) { validation_regex: "", required: false, locked: false, - default: field.default }; + if (field.default) { + data.default = field.default; + } + let sub_fields = []; switch (field.type) { @@ -111,12 +118,12 @@ function convertToHubspotField(field = {}) { display: "checkbox", }); case 'select': - const choices = []; - Object.keys(data.choices).forEach(value => choices.push([value, data.choices[value]])); + const options = []; + Object.keys(field.options).forEach(value => options.push([value, field.options[value]])); return Object.assign({}, data, { - type: "select", - choices: [choices] + type: "choice", + choices: options }); case 'link': return Object.assign({}, data, { @@ -224,18 +231,3 @@ function convertToHubspotField(field = {}) { }); } } - -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(' '); -} diff --git a/platforms/hubspot/hubspot-page-adapter.js b/platforms/hubspot/hubspot-page-adapter.js new file mode 100644 index 0000000..60b371c --- /dev/null +++ b/platforms/hubspot/hubspot-page-adapter.js @@ -0,0 +1,56 @@ +import path from "path"; +import {readFile, writeFile, mkdir, copyFile} from "fs/promises"; +import {copy} from "fs-extra"; +import {capitalize, getConfigs} from "../../helpers.js"; +import {convertToHubspotField, getBlockFields} from "./hubspot-email-adapter.js"; + +const {modulesPath, projectPath} = getConfigs(); + +export async function buildHubspotPage(blockName) { + const distPath = `./exports/hubspot/${blockName}.module`; + await mkdir(distPath, {recursive: true}) + await copyFile(`${projectPath}/src/${blockName}.template.hbs`, `${distPath}/module.html`) + await copyFile(`${projectPath}/src/styles/${blockName}.min.css`, `${distPath}/module.css`) + await copyFile(`${projectPath}/src/scripts/${blockName}.min.js`, `${distPath}/module.js`) + + await copy( + path.join(projectPath, 'src', 'images'), + path.join(distPath, 'images'), + ); + + const metaData = { + global: false, + host_template_types: ["PAGE"], + label: capitalize(blockName), + is_available_for_new_content: true + } + + await writeFile(`${distPath}/meta.json`, JSON.stringify(metaData, null, 4)); + + const blockJSON = await readFile(`${projectPath}/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", + }); + + stylingGroup.children = Object.values(stylingFieldsByName); + stylingGroup.tab = "STYLE"; + + fields.push(stylingGroup); + } + + // Export JSON file. + await writeFile(`${distPath}/fields.json`, JSON.stringify(fields, null, 4)); +} diff --git a/platforms/wordpress/wordpress-adapter.js b/platforms/wordpress/wordpress-adapter.js index 8faa611..ffd870d 100644 --- a/platforms/wordpress/wordpress-adapter.js +++ b/platforms/wordpress/wordpress-adapter.js @@ -1,9 +1,8 @@ import path from "path"; -import {mkdir, copyFile, readFile} from "fs/promises"; +import {mkdir, copyFile} from "fs/promises"; import {capitalize, createFiles, getBlockName, getConfigs, readJSONFile} from "../../helpers.js"; import {fileURLToPath} from 'url'; import {copy} from "fs-extra"; -import fsExtra from "fs-extra"; import {exec} from 'child_process'; import execPhp from "exec-php"; From 1ae643b306e56233acf9336fd2785cbb28709414 Mon Sep 17 00:00:00 2001 From: Roman Axelrod Date: Wed, 16 Nov 2022 22:28:17 +0200 Subject: [PATCH 2/4] Remove duplicated code. --- platforms/hubspot/hubspot-email-adapter.js | 72 ++++++++++++---------- platforms/hubspot/hubspot-page-adapter.js | 53 ++++------------ 2 files changed, 52 insertions(+), 73 deletions(-) diff --git a/platforms/hubspot/hubspot-email-adapter.js b/platforms/hubspot/hubspot-email-adapter.js index 9646851..4136b7e 100644 --- a/platforms/hubspot/hubspot-email-adapter.js +++ b/platforms/hubspot/hubspot-email-adapter.js @@ -1,48 +1,27 @@ +import path from "path"; import {readFile, writeFile, mkdir, copyFile} from "fs/promises"; import {capitalize, getConfigs} from "../../helpers.js"; const {modulesPath, projectPath} = getConfigs(); export async function buildHubspotEmail(blockName) { - const distPath = `./exports/hubspot/${blockName}.module`; - await mkdir(distPath, {recursive: true}) + const distPath = await createDistFolder(blockName); + await copyFile(`${projectPath}/src/${blockName}.template.hbs`, `${distPath}/module.html`) - const metaData = { + await buildHubspotJSONFiles(distPath, { 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(`${projectPath}/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", - }); - - stylingGroup.children = Object.values(stylingFieldsByName); - stylingGroup.tab = "STYLE"; + }); +} - fields.push(stylingGroup); - } +export async function createDistFolder(blockName) { + const distPath = path.join('exports', 'hubspot', `${blockName}.module`); + await mkdir(distPath, {recursive: true}) - // Export JSON file. - await writeFile(`${distPath}/fields.json`, JSON.stringify(fields, null, 4)); + return distPath; } export function getBlockFields(block = {}, type = 'content') { @@ -231,3 +210,34 @@ export function convertToHubspotField(field = {}) { }); } } + +export async function buildHubspotJSONFiles(distPath, metaData) { + await writeFile(path.join(distPath, 'meta.json'), JSON.stringify(metaData, null, 4)); + + const blockJSON = await readFile(path.join(projectPath, '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", + }); + + stylingGroup.children = Object.values(stylingFieldsByName); + stylingGroup.tab = "STYLE"; + + fields.push(stylingGroup); + } + + // Export JSON file. + await writeFile(path.join(distPath, 'fields.json'), JSON.stringify(fields, null, 4)); +} diff --git a/platforms/hubspot/hubspot-page-adapter.js b/platforms/hubspot/hubspot-page-adapter.js index 60b371c..3667abf 100644 --- a/platforms/hubspot/hubspot-page-adapter.js +++ b/platforms/hubspot/hubspot-page-adapter.js @@ -1,56 +1,25 @@ import path from "path"; -import {readFile, writeFile, mkdir, copyFile} from "fs/promises"; +import {copyFile} from "fs/promises"; import {copy} from "fs-extra"; import {capitalize, getConfigs} from "../../helpers.js"; -import {convertToHubspotField, getBlockFields} from "./hubspot-email-adapter.js"; +import {buildHubspotJSONFiles, createDistFolder,} from "./hubspot-email-adapter.js"; const {modulesPath, projectPath} = getConfigs(); export async function buildHubspotPage(blockName) { - const distPath = `./exports/hubspot/${blockName}.module`; - await mkdir(distPath, {recursive: true}) - await copyFile(`${projectPath}/src/${blockName}.template.hbs`, `${distPath}/module.html`) - await copyFile(`${projectPath}/src/styles/${blockName}.min.css`, `${distPath}/module.css`) - await copyFile(`${projectPath}/src/scripts/${blockName}.min.js`, `${distPath}/module.js`) + const distPath = await createDistFolder(blockName); - await copy( - path.join(projectPath, 'src', 'images'), - path.join(distPath, 'images'), - ); + const srcPath = path.join(projectPath, 'src'); + await copyFile(path.join(srcPath, `${blockName}.template.hbs`), path.join(distPath, 'module.html')); + await copyFile(path.join(srcPath, 'styles', `${blockName}.min.css`), path.join(distPath, 'module.css')); + await copyFile(path.join(srcPath, 'scripts', `${blockName}.min.js`), path.join(distPath, 'module.js')); + await copy(path.join(projectPath, 'src', 'images'), path.join(distPath, 'images')); - const metaData = { + await buildHubspotJSONFiles(distPath, { global: false, host_template_types: ["PAGE"], label: capitalize(blockName), is_available_for_new_content: true - } - - await writeFile(`${distPath}/meta.json`, JSON.stringify(metaData, null, 4)); - - const blockJSON = await readFile(`${projectPath}/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", - }); - - stylingGroup.children = Object.values(stylingFieldsByName); - stylingGroup.tab = "STYLE"; - - fields.push(stylingGroup); - } - - // Export JSON file. - await writeFile(`${distPath}/fields.json`, JSON.stringify(fields, null, 4)); + }); } + From a2f8c7ebc13aa6b9e60f3339cb97551a5f1cb027 Mon Sep 17 00:00:00 2001 From: Roman Axelrod Date: Wed, 16 Nov 2022 22:33:29 +0200 Subject: [PATCH 3/4] Make sure `options` field exists on select field. --- platforms/hubspot/hubspot-email-adapter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platforms/hubspot/hubspot-email-adapter.js b/platforms/hubspot/hubspot-email-adapter.js index 4136b7e..4b0dae5 100644 --- a/platforms/hubspot/hubspot-email-adapter.js +++ b/platforms/hubspot/hubspot-email-adapter.js @@ -98,7 +98,9 @@ export function convertToHubspotField(field = {}) { }); case 'select': const options = []; - Object.keys(field.options).forEach(value => options.push([value, field.options[value]])); + if (field.options) { + Object.keys(field.options).forEach(value => options.push([value, field.options[value]])); + } return Object.assign({}, data, { type: "choice", From 70d46309717bfcb7c1d04d3215213b1d4c089cf7 Mon Sep 17 00:00:00 2001 From: Roman Axelrod Date: Thu, 17 Nov 2022 00:32:11 +0200 Subject: [PATCH 4/4] Add basic Handlebars to Hubl converter. --- platforms/hubspot/hubspot-email-adapter.js | 25 +++++++++++++++++++++- platforms/hubspot/hubspot-page-adapter.js | 16 ++++++++------ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/platforms/hubspot/hubspot-email-adapter.js b/platforms/hubspot/hubspot-email-adapter.js index 4b0dae5..a1a689e 100644 --- a/platforms/hubspot/hubspot-email-adapter.js +++ b/platforms/hubspot/hubspot-email-adapter.js @@ -7,8 +7,11 @@ const {modulesPath, projectPath} = getConfigs(); export async function buildHubspotEmail(blockName) { const distPath = await createDistFolder(blockName); - await copyFile(`${projectPath}/src/${blockName}.template.hbs`, `${distPath}/module.html`) + // Template + let handlebars = await readFile(path.join(srcPath, `${blockName}.template.hbs`), "utf8"); + await writeFile(path.join(distPath, 'module.html'), handlebarsToHubl(handlebars)); + // JSON await buildHubspotJSONFiles(distPath, { global: false, host_template_types: ["EMAIL"], @@ -243,3 +246,23 @@ export async function buildHubspotJSONFiles(distPath, metaData) { // Export JSON file. await writeFile(path.join(distPath, 'fields.json'), JSON.stringify(fields, null, 4)); } + + +export function handlebarsToHubl(handlebars) { + handlebars = handlebars.replace(/{{#if /g, '{% if module.'); + handlebars = handlebars.replace(/{{\/if}}/g, '{% endif %}'); + handlebars = handlebars.replace(/{{#each /g, '{% for module.'); + handlebars = handlebars.replace(/{{\/each}}/g, '{% endfor %}'); + handlebars = handlebars.replace(/{{base_url}}/g, ''); + handlebars = handlebars.replace(/{esc_attr /g, '{'); + handlebars = handlebars.replace(/{esc_url /g, '{'); + handlebars = handlebars.replace(/{esc_html /g, '{'); + handlebars = handlebars.replace(/{{{ /g, '{{'); + handlebars = handlebars.replace(/ }}}/g, '}}'); + handlebars = handlebars.replace(/{{{/g, '{{'); + handlebars = handlebars.replace(/}}}/g, '}}'); + handlebars = handlebars.replace(/{{/g, '{{module.'); + handlebars = handlebars.replace(/{{module. /g, '{{ module.'); + + return handlebars; +} diff --git a/platforms/hubspot/hubspot-page-adapter.js b/platforms/hubspot/hubspot-page-adapter.js index 3667abf..616d133 100644 --- a/platforms/hubspot/hubspot-page-adapter.js +++ b/platforms/hubspot/hubspot-page-adapter.js @@ -1,8 +1,7 @@ import path from "path"; -import {copyFile} from "fs/promises"; -import {copy} from "fs-extra"; +import {copyFile, readFile, writeFile} from "fs/promises"; import {capitalize, getConfigs} from "../../helpers.js"; -import {buildHubspotJSONFiles, createDistFolder,} from "./hubspot-email-adapter.js"; +import {buildHubspotJSONFiles, createDistFolder, handlebarsToHubl,} from "./hubspot-email-adapter.js"; const {modulesPath, projectPath} = getConfigs(); @@ -10,11 +9,17 @@ export async function buildHubspotPage(blockName) { const distPath = await createDistFolder(blockName); const srcPath = path.join(projectPath, 'src'); - await copyFile(path.join(srcPath, `${blockName}.template.hbs`), path.join(distPath, 'module.html')); + + // Template + let handlebars = await readFile(path.join(srcPath, `${blockName}.template.hbs`), "utf8"); + await writeFile(path.join(distPath, 'module.html'), handlebarsToHubl(handlebars)); + + // Assets await copyFile(path.join(srcPath, 'styles', `${blockName}.min.css`), path.join(distPath, 'module.css')); await copyFile(path.join(srcPath, 'scripts', `${blockName}.min.js`), path.join(distPath, 'module.js')); - await copy(path.join(projectPath, 'src', 'images'), path.join(distPath, 'images')); + // await copy(path.join(projectPath, 'src', 'images'), path.join(distPath, 'images')); + // JSON await buildHubspotJSONFiles(distPath, { global: false, host_template_types: ["PAGE"], @@ -22,4 +27,3 @@ export async function buildHubspotPage(blockName) { is_available_for_new_content: true }); } -