build-wp-block #1
@@ -10,9 +10,4 @@ deploy-*.sh
|
||||
|
||||
# Custom
|
||||
blocks
|
||||
config
|
||||
data
|
||||
src
|
||||
exports
|
||||
block.json
|
||||
design
|
||||
|
||||
@@ -5,9 +5,11 @@ import config from 'config';
|
||||
import Generator from "yeoman-generator";
|
||||
import yeoman from 'yeoman-environment';
|
||||
import {buildHubspot} from "./platforms/hubspot/hubspot-adapter.js";
|
||||
import {getConfigs} from "./helpers.js";
|
||||
import {buildWordPress} from "./platforms/wordpress/wordpress-adapter.js";
|
||||
import path from "path";
|
||||
|
||||
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/block-dev-tool/';
|
||||
const {modulesPath, projectPath} = getConfigs();
|
||||
|
||||
const blockName = config.has('blockName') ? config.get('blockName') : 'development';
|
||||
|
||||
@@ -18,7 +20,7 @@ class buildGenerator extends Generator {
|
||||
type: "list",
|
||||
name: "platform",
|
||||
message: "Choose Platform",
|
||||
choices: ['WordPress', 'Hubspot', 'Hubspot Email', 'JavaScript', 'PHP'],
|
||||
choices: ['WordPress', 'WordPress Block', 'Hubspot', 'Hubspot Email', 'JavaScript', 'PHP'],
|
||||
default: 'WordPress'
|
||||
}
|
||||
])
|
||||
@@ -27,11 +29,29 @@ class buildGenerator extends Generator {
|
||||
writing() {
|
||||
new Promise((resolve => {
|
||||
if (['WordPress', 'PHP'].includes(this.data.platform)) {
|
||||
const backPath = modulePath ? modulePath.substr(-1).split('/').map(() => '..').join('/') : '';
|
||||
exec(`cd ${modulePath}platforms/php && composer install && php build.php '${blockName}' '${backPath}'`, function (error, stdout) {
|
||||
console.log(stdout);
|
||||
resolve();
|
||||
const backPath = modulesPath ? modulesPath.split('/').map(() => '..').join('/') : '';
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const phpGeneratorPath = path.join(modulesPath, 'platforms', 'php');
|
||||
exec(`cd ${phpGeneratorPath} && composer install && php build.php '${blockName}' '${backPath}' '${projectPath}'`, function (error, stdout) {
|
||||
if (error) {
|
||||
console.log('Error:', error)
|
||||
reject(error);
|
||||
}
|
||||
|
||||
console.log(stdout);
|
||||
resolve();
|
||||
});
|
||||
}).then(() => {
|
||||
if (this.data.platform === 'WordPress') {
|
||||
return buildWordPress();
|
||||
}
|
||||
|
||||
if (this.data.platform === 'WordPress Block') {
|
||||
return buildWordPress(true);
|
||||
}
|
||||
});
|
||||
|
||||
} else if (this.data.platform === 'Hubspot Email') {
|
||||
buildHubspot(blockName)
|
||||
.then(() => {
|
||||
@@ -50,6 +70,5 @@ class buildGenerator extends Generator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const build = new buildGenerator([], {env: yeoman.createEnv()}, {});
|
||||
build.run().then(() => null);
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
import path from 'path';
|
||||
import config from 'config';
|
||||
import {fileURLToPath} from 'url';
|
||||
import memFs from 'mem-fs';
|
||||
import editor from 'mem-fs-editor';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
export function getConfigs() {
|
||||
const isDev = process.env.NODE_ENV === 'development'; // Check README file in case you get "missing files" error.
|
||||
const developmentBlockName = process.env.BLOCK_NAME;
|
||||
|
||||
return {
|
||||
isDev,
|
||||
developmentBlockName,
|
||||
modulesPath: isDev ? '' : 'node_modules/block-dev-tool',
|
||||
projectPath: isDev ? path.join('blocks', developmentBlockName) : '',
|
||||
};
|
||||
}
|
||||
|
||||
import fsExtra from "fs-extra";
|
||||
|
||||
export async function readJSONFile(jsonFile) {
|
||||
let data = {};
|
||||
|
||||
try {
|
||||
data = await fsExtra.readJson(jsonFile);
|
||||
} catch (e) {
|
||||
return {
|
||||
error: true, errorMessage: getErrorHtml("JSON Syntax error. Please make sure the dataFile is valid.", e),
|
||||
};
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function getErrorHtml(message = '', errorMessage = '') {
|
||||
return `<div style="padding: 10px 15px; font-family: Arial, sans-serif">
|
||||
<p>${message}</p>
|
||||
<pre style="padding: 10px 15px; background-color: #ffd0d0; border: 1px solid red;">${errorMessage}</pre>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
export async function getBlockConfigs(jsonFileName = 'default',
|
||||
{includeConfigs, projectPath, modulesPath, dataFiles} = {}) {
|
||||
let data = await readJSONFile(path.join(projectPath, 'data', `${jsonFileName}.json`));
|
||||
if (data.error) {
|
||||
return data;
|
||||
}
|
||||
|
||||
if (includeConfigs) {
|
||||
Object.assign(data, {
|
||||
config: Object.assign(JSON.parse(JSON.stringify(config)), // The entire config object.
|
||||
{
|
||||
projectDir: modulesPath, activeDataFile: jsonFileName, dataFiles: dataFiles.map((name) => {
|
||||
return {
|
||||
name, active: jsonFileName === name,
|
||||
};
|
||||
}), remToPx: config.has('remToPx') ? config.get('remToPx') : 16,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
export function getBlockName(name = '') {
|
||||
if (name.startsWith('@')) {
|
||||
name = name.substring(1);
|
||||
}
|
||||
|
||||
const arr = name.split('/');
|
||||
|
||||
return {
|
||||
project: arr[0],
|
||||
name: arr[1],
|
||||
};
|
||||
}
|
||||
|
||||
export async function createFiles(data, files = [], {pathDist, generatorsPath}) {
|
||||
generatorsPath = generatorsPath ?? path.join(__dirname, 'generators/block/templates');
|
||||
|
||||
const store = memFs.create();
|
||||
const filesystem = editor.create(store);
|
||||
for (let file of files) {
|
||||
const from = typeof file !== 'string' ? `${generatorsPath}/${file.from}` : `${generatorsPath}/${file}`;
|
||||
const to = typeof file !== 'string' ? `${pathDist}/${file.to}` : `${pathDist}/${file}`;
|
||||
|
||||
await filesystem.copyTplAsync(from, to, data);
|
||||
}
|
||||
|
||||
return filesystem.commit(); // Promise
|
||||
}
|
||||
|
||||
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(' ');
|
||||
}
|
||||
@@ -1,18 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const heightLimit = window.outerHeight * 2;
|
||||
let height = getCurrentHeight();
|
||||
setupResizeListener();
|
||||
|
||||
///
|
||||
|
||||
function setupResizeListener() {
|
||||
const RESIZE_CODE = 'resize:';
|
||||
|
||||
const resizeObserver = new ResizeObserver(entries => {
|
||||
setTimeout(() => {
|
||||
const height = document.body.scrollHeight;
|
||||
window.parent.postMessage(RESIZE_CODE + JSON.stringify({height}), '*');
|
||||
}, 200);
|
||||
})
|
||||
|
||||
const resizeObserver = new ResizeObserver(handleHeightChange);
|
||||
resizeObserver.observe(document.body);
|
||||
}
|
||||
|
||||
function handleHeightChange(entries) {
|
||||
const updatedHeight = getCurrentHeight();
|
||||
if (height === updatedHeight || updatedHeight > heightLimit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const RESIZE_CODE = 'resize:';
|
||||
window.parent.postMessage(RESIZE_CODE + JSON.stringify({height}), '*');
|
||||
height = updatedHeight;
|
||||
}
|
||||
|
||||
function getCurrentHeight() {
|
||||
return document.querySelector('body > main').scrollHeight;
|
||||
}
|
||||
|
||||
Generated
+257
-890
File diff suppressed because it is too large
Load Diff
+6
-2
@@ -8,9 +8,9 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "component-dev",
|
||||
"dev": "NODE_ENV=development node server.js",
|
||||
"dev": "NODE_ENV=development NODE_CONFIG_DIR=blocks/team/config BLOCK_NAME=team node server.js",
|
||||
"build": "rollup --config rollup.config.js",
|
||||
"build-platform": "NODE_ENV=development node ./build.js",
|
||||
"build-platform": "NODE_ENV=development NODE_CONFIG_DIR=blocks/team/config BLOCK_NAME=team node ./build.js",
|
||||
"build-platform-cli": "component-build",
|
||||
"dev-js": "rollup --config rollup.config.js --watch"
|
||||
},
|
||||
@@ -32,8 +32,11 @@
|
||||
"gulp-sourcemaps": "^3.0.0",
|
||||
"gulp-uglify": "^3.0.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mem-fs": "^2.2.1",
|
||||
"mem-fs-editor": "^9.5.0",
|
||||
"node-fetch": "^3.2.10",
|
||||
"open": "^8.4.0",
|
||||
"plugin-error": "^2.0.0",
|
||||
"sanitize-html": "^2.7.1",
|
||||
"sass": "^1.50.1",
|
||||
"yeoman-environment": "^3.10.0",
|
||||
@@ -58,6 +61,7 @@
|
||||
"component-build": "./build.js"
|
||||
},
|
||||
"files": [
|
||||
"helpers.js",
|
||||
"layouts/**/*",
|
||||
"platforms/**/*"
|
||||
]
|
||||
|
||||
@@ -54,14 +54,15 @@ class Component_Builder {
|
||||
public string $component_name = '';
|
||||
private string $module_path = '';
|
||||
|
||||
function __construct( $component_name, $module_path ) {
|
||||
function __construct( $component_name, $module_path, $project_path ) {
|
||||
$this->module_path = $module_path;
|
||||
$this->project_path = $project_path;
|
||||
$this->component_name = $component_name;
|
||||
$this->register_default_handlebar_helpers();
|
||||
}
|
||||
|
||||
function build(): void {
|
||||
$root_path = __DIR__ . '/' . $this->module_path . '/../..';
|
||||
$root_path = __DIR__ . '/' . $this->module_path . '/../../' . $this->project_path;
|
||||
$file_name = $this->get_handlebars_template( "$root_path/src/$this->component_name.template.hbs" );
|
||||
|
||||
$output_folder = $root_path . '/exports/wordpress/templates';
|
||||
@@ -122,4 +123,4 @@ class Component_Builder {
|
||||
}
|
||||
}
|
||||
|
||||
( new Component_Builder( $argv[1], $argv[2] ) )->build();
|
||||
( new Component_Builder( $argv[1], $argv[2], $argv[3] ) )->build();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Core\Global_Functions;
|
||||
|
||||
class <%= blockClassModel %>_Component {
|
||||
|
||||
public function __construct() {
|
||||
add_action( 'wp_enqueue_scripts', [ $this, 'register_assets' ] );
|
||||
}
|
||||
|
||||
function register_assets(): void {
|
||||
wp_enqueue_style( '<%= blockFilename %>',
|
||||
get_template_directory_uri() . '/components/partials/<%= blockFilename %>/templates/styles/<%= blockFilename %>.min.css',
|
||||
[ 'style-wp' ],
|
||||
Global_Functions::get_current_version_number()
|
||||
);
|
||||
|
||||
wp_enqueue_script( '<%= blockFilename %>',
|
||||
get_template_directory_uri() . '/components/partials/<%= blockFilename %>/templates/scripts/<%= blockFilename %>.min.js',
|
||||
[ 'jquery', 'swiper' ],
|
||||
Global_Functions::get_current_version_number(),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
public function render( $args = [] ): void {
|
||||
$output = ( include( __DIR__ . '/templates/<%= blockFilename %>.template.php' ) )( array_merge( [], $args ), self::class );
|
||||
echo apply_filters( 'the_content', wpautop( $output ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace AXEWEB_Blocks\Blocks\<%= ownerClass %>\<%= blockClassModel %>;
|
||||
|
||||
class <%= blockClassModel %>_Component extends \Core\Component {
|
||||
|
||||
public function get_content( $args = [] ): string {
|
||||
$args = array_merge( Helpers\<%= blockClassModel %>_Defaults::default_args(), $args );
|
||||
$args = Helpers\<%= blockClassModel %>_API::prepare_args( $args );
|
||||
|
||||
<% if (templateFormat === 'hbs') { %>return $this->get_component_template( __DIR__ . '/templates/<%= blockFilename %>.template.hbs', $args );<% } %>
|
||||
<% if (templateFormat === 'php') { %>
|
||||
$output = ( include( __DIR__ . '/templates/<%= blockFilename %>.template.php' ) )( array_merge( [], $args ), self::class );
|
||||
echo apply_filters( 'the_content', wpautop( $output ) );
|
||||
<% } %>
|
||||
}
|
||||
|
||||
<% if (!include_acf_block && !include_native_gutenberg_block) { %>
|
||||
public function register_assets() {
|
||||
$this->add_style( __DIR__ . '/templates/styles/<%= blockFilename %>.min.css' );
|
||||
<% if (include_script) { %>$this->add_script( __DIR__ . '/templates/scripts/<%= blockFilename %>.js' );<% } %>
|
||||
}
|
||||
|
||||
<% } %><% if (include_elementor_widget) { %> function register_custom_logic(): void {
|
||||
add_action( 'elementor/widgets/widgets_registered', [ $this, 'register_elementor_widget' ] );
|
||||
}
|
||||
|
||||
<% } %><% if (include_elementor_widget) { %> function register_elementor_widget( $widgets_manager ) {
|
||||
$widgets_manager->register_widget_type( new Helpers\<%= blockClassModel %>_Elementor_Widget() );
|
||||
}
|
||||
|
||||
<% } %><% if (include_acf_block) { %> function register_acf_block() {
|
||||
$this->register_block( __DIR__ . "/<%= blockFilename %>.block.json", [
|
||||
'enqueue_assets' => function () {
|
||||
wp_enqueue_style( '<%= blockFilename %>', \Core\Global_Functions::get_file_url( __DIR__ . '/templates/styles/<%= blockFilename %>.min.css', true ), [], get_blocks_version() );<% if (include_script) { %>
|
||||
wp_enqueue_script( '<%= blockFilename %>', \Core\Global_Functions::get_file_url( __DIR__ . '/templates/scripts/<%= blockFilename %>.js', true ), ['assets-script'], get_blocks_version() );<% } %>
|
||||
},
|
||||
'default' => Helpers\<%= blockClassModel %>_Defaults::default_args(),
|
||||
'supports' => [
|
||||
//'jsx' => true,
|
||||
'color' => [
|
||||
'background' => true,
|
||||
'text' => true,
|
||||
],
|
||||
'spacing' => [
|
||||
'margin' => [ 'top', 'bottom' ],
|
||||
'padding' => [ 'top', 'bottom' ]
|
||||
],
|
||||
]
|
||||
] );
|
||||
}
|
||||
|
||||
<% } %><% if (include_native_gutenberg_block) { %> function register_native_gutenberg_block() {
|
||||
register_block_type( __DIR__ . '/templates/gutenberg-block/block.json' );<% if (include_script) { %>
|
||||
|
||||
add_action( 'wp_enqueue_scripts', function () {
|
||||
$asset_file_front = include( plugin_dir_path( __FILE__ ) . '/templates/gutenberg-block/build/front.asset.php' );
|
||||
wp_enqueue_script(
|
||||
'gutenberg-<%= blockFilename %>-scripts-front',
|
||||
plugins_url( 'templates/gutenberg-block/build/front.js', __FILE__ ),
|
||||
$asset_file_front['dependencies'],
|
||||
$asset_file_front['version'],
|
||||
true
|
||||
);
|
||||
} );<% } %>
|
||||
}<% } %>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace AXEWEB_Blocks\Blocks\<%= ownerClass %>\<%= blockClassModel %>\Helpers;
|
||||
|
||||
class <%= blockClassModel %>_API {
|
||||
|
||||
static function prepare_args( $args = [] ) {
|
||||
|
||||
// $args = array_merge( [], $args );
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace AXEWEB_Blocks\Blocks\<%= ownerClass %>\<%= blockClassModel %>\Helpers;
|
||||
|
||||
/**
|
||||
* Component's default args.
|
||||
*/
|
||||
|
||||
class <%= blockClassModel %>_Defaults {
|
||||
public static function default_args(): array {
|
||||
return [
|
||||
'title' => '<%= title %>',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import path from "path";
|
||||
import {mkdir, copyFile} from "fs/promises";
|
||||
import {capitalize, createFiles, getBlockName, getConfigs, readJSONFile} from "../../helpers.js";
|
||||
import {fileURLToPath} from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const {projectPath} = getConfigs();
|
||||
|
||||
export async function buildWordPress(isBlock = false) {
|
||||
const distPath = path.join(projectPath, 'exports', 'wordpress');
|
||||
await mkdir(distPath, {recursive: true})
|
||||
|
||||
const jsonFilePath = path.join(projectPath, 'block.json');
|
||||
await copyFile(jsonFilePath, `${distPath}/block.json`)
|
||||
|
||||
let data = await readJSONFile(jsonFilePath);
|
||||
Object.assign(data, getBlockName(data.name));
|
||||
|
||||
// let data = await readJSONFile(path.join(projectPath, `block.json`));
|
||||
const title = capitalize(data.name);
|
||||
const owner = capitalize(data.project);
|
||||
|
||||
data = Object.assign(data, {
|
||||
title,
|
||||
blockClassModel: title.replace(/ /ig, '_'),
|
||||
blockFilename: title.toLowerCase().replace(/ /ig, '-'),
|
||||
blockClassName: title.toLowerCase().replace(/ /ig, '_'),
|
||||
owner,
|
||||
ownerClass: owner.replace(/ /ig, '_'),
|
||||
ownerFilename: owner.toLowerCase().replace(/ /ig, '-'),
|
||||
templateFormat: 'php',
|
||||
include_acf_block: false,
|
||||
include_native_gutenberg_block: false,
|
||||
include_script: true,
|
||||
include_elementor_widget: false,
|
||||
});
|
||||
|
||||
if (isBlock) {
|
||||
await createFiles(data, [{
|
||||
from: `templates/Template_Component.php`,
|
||||
to: `${data.blockClassModel}_Component.php`,
|
||||
}], {
|
||||
pathDist: distPath,
|
||||
generatorsPath: path.join(__dirname)
|
||||
});
|
||||
|
||||
await createFiles(data, [{
|
||||
from: `templates/helpers/Template_API.php`,
|
||||
to: `helpers/${data.blockClassModel}_API.php`,
|
||||
}], {
|
||||
pathDist: distPath,
|
||||
generatorsPath: path.join(__dirname)
|
||||
});
|
||||
|
||||
await createFiles(data, [{
|
||||
from: `templates/helpers/Template_Defaults.php`,
|
||||
to: `helpers/${data.blockClassModel}_Defaults.php`,
|
||||
}], {
|
||||
pathDist: distPath,
|
||||
generatorsPath: path.join(__dirname)
|
||||
});
|
||||
} else {
|
||||
await createFiles(data, [{
|
||||
from: `templates/Template_Basic_Component.php`,
|
||||
to: `${data.blockClassModel}_Component.php`,
|
||||
}], {
|
||||
pathDist: distPath,
|
||||
generatorsPath: path.join(__dirname)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import path from 'path';
|
||||
import fetch from "node-fetch";
|
||||
import express from 'express';
|
||||
import {create} from 'express-handlebars';
|
||||
@@ -19,29 +20,25 @@ import {sanitizeUrl} from "@braintree/sanitize-url";
|
||||
import sanitizeHtml from 'sanitize-html';
|
||||
import {escape} from "lodash-es";
|
||||
import archiver from 'archiver';
|
||||
import {getBlockConfigs, getConfigs, readJSONFile} from "./helpers.js";
|
||||
import PluginError from 'plugin-error';
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
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, modulesPath, projectPath, developmentBlockName} = getConfigs();
|
||||
const blocksRegistry = isDev ? 'http://localhost:3020' : 'https://axe-web-blocks-registry.captain.devdevdev.life';
|
||||
const modulePath = isDev ? '' : 'node_modules/block-dev-tool/';
|
||||
const projectDir = modulePath;
|
||||
|
||||
const sass = gulpSass(dartSass);
|
||||
|
||||
buildStyleFiles()
|
||||
buildScriptFiles()
|
||||
|
||||
/**
|
||||
* Init server
|
||||
*/
|
||||
|
||||
let port = 3000; // This variable is used in `*.hbs` and it will be updated once BrowserSync is ready.
|
||||
let previewFrameUrl = `http://localhost:${port}`; // This variable is used in *.hbs and it will be updated once BrowserSync is ready.
|
||||
const dataFiles = prepareListOfDataFiles(await fs.readdir('./data'));
|
||||
let previewFrameUrl = `http://localhost:${port}`; // This variable is used in `*.hbs` and it will be updated once BrowserSync is ready.
|
||||
const dataFiles = prepareListOfDataFiles(await fs.readdir(path.join(projectPath, 'data')));
|
||||
const app = express();
|
||||
const sass = gulpSass(dartSass);
|
||||
|
||||
const hbs = create({
|
||||
extname: '.hbs', defaultLayout: false, partialsDir: ['.'], helpers: {
|
||||
@@ -60,7 +57,7 @@ const hbs = create({
|
||||
|
||||
app.engine('.hbs', hbs.engine);
|
||||
app.set('view engine', '.hbs');
|
||||
app.set('views', projectDir + 'layouts');
|
||||
app.set('views', path.join(modulesPath, 'layouts'));
|
||||
|
||||
//
|
||||
// Routes
|
||||
@@ -68,7 +65,7 @@ app.set('views', projectDir + 'layouts');
|
||||
|
||||
app.get('/', async (req, res) => {
|
||||
let jsonFileName = req.query.data ? req.query.data : 'default';
|
||||
const data = await getBlockConfigs(jsonFileName, {includeConfigs: true});
|
||||
const data = await getBlockConfigs(jsonFileName, {includeConfigs: true, projectPath, modulesPath, dataFiles});
|
||||
if (data.error && data.errorMessage) {
|
||||
return res.send(data.errorMessage);
|
||||
}
|
||||
@@ -78,7 +75,7 @@ app.get('/', async (req, res) => {
|
||||
|
||||
data.helpers = {
|
||||
port,
|
||||
include_partial: (path) => projectDir + path,
|
||||
include_partial: (filesPath) => path.join(modulesPath, filesPath),
|
||||
baseView,
|
||||
previewFrameUrl: `${previewFrameUrl}/${baseViewUrl}`,
|
||||
}
|
||||
@@ -88,16 +85,16 @@ app.get('/', async (req, res) => {
|
||||
|
||||
app.get('/view/:baseView', async (req, res) => {
|
||||
let jsonFileName = req.query.data ? req.query.data : 'default';
|
||||
const data = await getBlockConfigs(jsonFileName, {includeConfigs: true});
|
||||
const data = await getBlockConfigs(jsonFileName, {includeConfigs: true, projectPath, modulesPath, dataFiles});
|
||||
if (data.error && data.errorMessage) {
|
||||
return res.send(data.errorMessage);
|
||||
}
|
||||
|
||||
const blockName = config.has('blockName') ? config.get('blockName') : 'development';
|
||||
const blockName = config.has('blockName') ? config.get('blockName') : developmentBlockName;
|
||||
|
||||
data.helpers = {
|
||||
include_partial: (path) => projectDir + path,
|
||||
include_block_template: (path) => `src/${blockName}.template`,
|
||||
include_partial: (filesPath) => path.join(modulesPath, filesPath),
|
||||
include_block_template: () => path.join(projectPath, 'src', `${blockName}.template`),
|
||||
section_class: `${blockName}--${jsonFileName}`,
|
||||
base_url: '/'
|
||||
}
|
||||
@@ -108,7 +105,7 @@ app.get('/view/:baseView', async (req, res) => {
|
||||
});
|
||||
|
||||
app.get('/publish', async (req, res) => {
|
||||
const data = await readJSONFile('./block.json');
|
||||
const data = await readJSONFile(path.join(projectPath, `block.json`));
|
||||
let responseData;
|
||||
|
||||
try {
|
||||
@@ -131,7 +128,7 @@ app.get('/publish', async (req, res) => {
|
||||
|
||||
if (responseData.uploadUrl) {
|
||||
await zipProject();
|
||||
const body = await fs.readFile('./dist.zip');
|
||||
const body = await fs.readFile(path.join(projectPath, 'dist.zip'));
|
||||
const response = await fetch(`${responseData.uploadUrl}`, {
|
||||
method: 'PUT',
|
||||
body,
|
||||
@@ -141,7 +138,7 @@ app.get('/publish', async (req, res) => {
|
||||
if (response.status !== 200) {
|
||||
res.json({success: false, message: "Can't upload the archive, permissions error."});
|
||||
// TODO: Need to update the registry server.
|
||||
await fs.unlink('./dist.zip');
|
||||
await fs.unlink(path.join(projectPath, 'dist.zip'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -149,15 +146,15 @@ app.get('/publish', async (req, res) => {
|
||||
|
||||
res.json({success: true});
|
||||
|
||||
await fs.unlink('./dist.zip');
|
||||
await fs.unlink(path.join(projectPath, 'dist.zip'));
|
||||
});
|
||||
|
||||
app.get('/data', async (req, res) => {
|
||||
let jsonDataFileName = req.query.name ? req.query.name : 'default';
|
||||
const data = await getBlockConfigs(jsonDataFileName);
|
||||
|
||||
const dataFiles = prepareListOfDataFiles(await fs.readdir('./data'));
|
||||
const designPreviewFiles = getListOfDesignPreviewFiles(jsonDataFileName, await fs.readdir('./design/preview'));
|
||||
const dataFiles = prepareListOfDataFiles(await fs.readdir(path.join(projectPath, 'data')));
|
||||
const data = await getBlockConfigs(jsonDataFileName, {projectPath, modulesPath, dataFiles});
|
||||
const designPreviewFiles = getListOfDesignPreviewFiles(jsonDataFileName, await fs.readdir(path.join(projectPath, 'design', 'preview')));
|
||||
|
||||
return res.json({
|
||||
dataOptions: dataFiles,
|
||||
@@ -170,9 +167,12 @@ app.get('/data', async (req, res) => {
|
||||
app.use(handleSyntaxErrors);
|
||||
|
||||
// Static Files
|
||||
app.use(express.static('src'));
|
||||
app.use(express.static('design'));
|
||||
app.use(express.static(projectDir + 'layouts'));
|
||||
app.use(express.static(path.join(projectPath, 'src')));
|
||||
app.use(express.static(path.join(projectPath, 'design')));
|
||||
app.use(express.static(path.join(modulesPath, 'layouts')));
|
||||
|
||||
// Setup Gulp
|
||||
await buildAssetFiles();
|
||||
|
||||
// BrowserSync
|
||||
const bsOptions = await startBrowserSync();
|
||||
@@ -212,12 +212,13 @@ function startBrowserSync() {
|
||||
|
||||
const bs = browserSync.create();
|
||||
|
||||
gulp.watch(['src/**/*.js', 'src/**/*.mjs', '!src/**/*.min.js'], {delay: 400}, gulp.series([buildScriptFiles, function (cb) {
|
||||
const files = getJSBundleFiles();
|
||||
gulp.watch(files, {delay: 400}, gulp.series(['build-script-files', function (cb) {
|
||||
browserSyncReload(bs, 'js', 'Script Files Change');
|
||||
return cb();
|
||||
}]));
|
||||
|
||||
gulp.watch('src/**/*.scss', {delay: 400}, gulp.series([buildStyleFiles, function (cb) {
|
||||
gulp.watch(path.join(projectPath, 'src/**/*.scss'), {delay: 400}, gulp.series(['build-styling-files', function (cb) {
|
||||
browserSyncReload(bs, 'css', 'Style Files Change');
|
||||
return cb();
|
||||
}]));
|
||||
@@ -259,26 +260,58 @@ function browserSyncReload(bs, extension = '', message = '') {
|
||||
bs.reload(extension);
|
||||
}
|
||||
|
||||
function buildScriptFiles() {
|
||||
return gulp.src(['src/**/*.js', 'src/**/*.mjs', '!src/**/*.min.js'])
|
||||
function getJSBundleFiles() {
|
||||
return [path.join(projectPath, 'src/**/*.js'), path.join(projectPath, 'src/**/*.mjs'), '!' + path.join(projectPath, 'src/**/*.min.js')];
|
||||
}
|
||||
|
||||
function buildScriptFiles(done) {
|
||||
const files = getJSBundleFiles();
|
||||
return gulp.src(files)
|
||||
.pipe(sourcemaps.init({}))
|
||||
.pipe(babel())
|
||||
.pipe(gulp.src('vendor/*.js'))
|
||||
.pipe(babel()).on('error', function (error) {
|
||||
showError(new PluginError('JavaScript', error).toString());
|
||||
done();
|
||||
})
|
||||
.pipe(gulp.src(path.join(projectPath, 'vendor/*.js')))
|
||||
// .pipe(gulp.dest('src/'))
|
||||
.pipe(uglify())
|
||||
.pipe(rename({extname: '.min.js'}))
|
||||
.pipe(sourcemaps.write('.'))
|
||||
.pipe(gulp.dest('src/'));
|
||||
.pipe(gulp.dest(path.join(projectPath, 'src/')));
|
||||
}
|
||||
|
||||
function buildStyleFiles() {
|
||||
return gulp.src('src/**/*.scss')
|
||||
function buildStyleFiles(done) {
|
||||
return gulp.src(path.join(projectPath, 'src/**/*.scss'))
|
||||
.pipe(sourcemaps.init({}))
|
||||
.pipe(sass.sync().on('error', sass.logError))
|
||||
.pipe(sass.sync({outputStyle: 'compressed'}).on('error', function (error) {
|
||||
showError(new PluginError('SCSS', error.messageFormatted).toString());
|
||||
// sass.logError(error);
|
||||
done();
|
||||
}))
|
||||
// .pipe(gulp.dest('src/'))
|
||||
.pipe(rename({extname: '.min.css'}))
|
||||
.pipe(sourcemaps.write('.'))
|
||||
.pipe(gulp.dest('src/'))
|
||||
.pipe(sourcemaps.write('.', {}))
|
||||
.pipe(gulp.dest(path.join(projectPath, 'src')))
|
||||
}
|
||||
|
||||
function buildAssetFiles() {
|
||||
// Register tasks.
|
||||
gulp.task('build-script-files', buildScriptFiles);
|
||||
gulp.task('build-styling-files', buildStyleFiles);
|
||||
|
||||
// Run first build.
|
||||
return new Promise((resolve) => {
|
||||
gulp.series('build-script-files', 'build-styling-files', function (cb) {
|
||||
resolve();
|
||||
})();
|
||||
});
|
||||
}
|
||||
|
||||
function showError(errorMessage) {
|
||||
console.log(errorMessage);
|
||||
|
||||
// TODO: Send this message to browser.
|
||||
// So the developer can understand there is an error.
|
||||
}
|
||||
|
||||
function prepareListOfDataFiles(dataFiles) {
|
||||
@@ -292,48 +325,6 @@ function prepareListOfDataFiles(dataFiles) {
|
||||
.sort();
|
||||
}
|
||||
|
||||
async function readJSONFile(jsonFile) {
|
||||
let data = {};
|
||||
|
||||
try {
|
||||
data = await fsExtra.readJson(jsonFile);
|
||||
} catch (e) {
|
||||
return {
|
||||
error: true, errorMessage: getErrorHtml("JSON Syntax error. Please make sure the dataFile is valid.", e),
|
||||
};
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async function getBlockConfigs(jsonFileName = 'default', {includeConfigs} = {}) {
|
||||
let data = await readJSONFile(`./data/${jsonFileName}.json`);
|
||||
if (data.error) {
|
||||
return data;
|
||||
}
|
||||
|
||||
if (includeConfigs) {
|
||||
Object.assign(data, {
|
||||
config: Object.assign(JSON.parse(JSON.stringify(config)), // The entire config object.
|
||||
{
|
||||
projectDir, activeDataFile: jsonFileName, dataFiles: dataFiles.map((name) => {
|
||||
return {
|
||||
name, active: jsonFileName === name,
|
||||
};
|
||||
}), remToPx: config.has('remToPx') ? config.get('remToPx') : 16,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function getErrorHtml(message = '', errorMessage = '') {
|
||||
return `<div style="padding: 10px 15px; font-family: Arial, sans-serif">
|
||||
<p>${message}</p>
|
||||
<pre style="padding: 10px 15px; background-color: #ffd0d0; border: 1px solid red;">${errorMessage}</pre>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
async function zipProject() {
|
||||
// create a file to stream archive data to.
|
||||
@@ -372,8 +363,8 @@ async function zipProject() {
|
||||
// pipe archive data to the file
|
||||
archive.pipe(output);
|
||||
|
||||
// append files from a sub-directory, putting its contents at the root of archive
|
||||
archive.directory('src/', false);
|
||||
// append files from a subdirectory, putting its contents at the root of archive
|
||||
archive.directory(path.join(projectPath, 'src', '/'), false);
|
||||
|
||||
// finalize the archive (ie we are done appending files but streams have to finish yet)
|
||||
// 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand
|
||||
@@ -384,7 +375,7 @@ function handleSyntaxErrors(err, req, res, next) {
|
||||
if (err) {
|
||||
return res.render('error', {
|
||||
helpers: {
|
||||
include_partial: (path) => projectDir + path,
|
||||
include_partial: (filesPath) => path.join(modulesPath, filesPath),
|
||||
},
|
||||
err
|
||||
});
|
||||
@@ -392,4 +383,3 @@ function handleSyntaxErrors(err, req, res, next) {
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user