Add block generator logic.

Now we are able to generate new blocks with yeoman.
This commit is contained in:
2022-04-30 01:04:36 +03:00
parent d3b25e2ef5
commit 82362b3ab2
23 changed files with 26579 additions and 12478 deletions
+1
View File
@@ -9,3 +9,4 @@ deploy.sh
deploy-*.sh
# Custom
blocks
+15 -148
View File
@@ -1,155 +1,22 @@
# Development Setup
# Create Block - Development Tool
Install required modules:
This project used as:
```sh
npm install
1. Block generator
2. Development Environment
## Block Generator
To create/generate new block by template use:
```
npm run generate-block
```
Run development environment:
```sh
npm start
```
## How it works ⚙️
The project runs `gulp` and `browsersync` beyond the scenes.
Each change in template, styling or script files will reload the page. The idea is to have a comfortable development
The `/blocks` folder will be generated. Then you can run `npm install`, `npm start` to launch the development
environment.
# Block Structure
## Development Environment
You will find all the block files in `/src` folder.
```
/src/images/
*.png, *jpg, *.svg
/src/scritps/
*.mjs, *js
/src/styles/
*.scss
/src/*.template.hbs
```
# Block rules
We have a “blocks system”, means you will have to follow strict rules and use listed technologies:
## Template Layout & Data
### Data
You will find multiple `*.json` files in `/data` folder after the first run of `npm start`.
These files are used as data sources in layout. By reviewing these files you can understand what parameters you have and
how the data is stored.
There are multiple data sources since the block can be reused in different situations with different data. We have to
make sure that the block is always rendered properly.
> Don't change or edit these files - use the data as it is!
### Handlebars
[Handlebars](https://handlebarsjs.com/guide/ "What is Handlebars") used as a template engine in the project.
All the template layout must be in a single `*.hbs` file that located in `/src` folder.
> Use the data that is available in `/data` folder.
> Avoid using any kind of "freestyle" input/content. Your template file must contain only HTML tags and Handlebars parameters.
### Static Media Files 🖼️
Use the `/src/images` folder in case you need to upload images or video files to the template.
These files will be available by the next URL: http://localhost:3000/images/${filename}
### Class Naming Convention
Use BEM naming system for class names: http://getbem.com/naming/
## Styling rules 🎨
### Mobile First 📱
Use Mobile First approach. Start with mobile device styling and then focus on other screen sizes by using @media (
min-width: ...px).
### CSS Units
Use `rem` units instead of pixels.
For example, `1rem = 16pixels` depends on project.
No need to use rem in situations of `1px`, `2px` or `3px`. (usually used for borders width).
It's important to mention that the block is "elastic". By using `rem` units we are able to scale the layout and keep the
aspect ratio.
### Global Styling
The development environment includes CSS rules of the original project. This is including fonts, CSS variables,
container logic etc...
The CSS file is already embedded in served HTML.
# JavaScript
## Sliders
For any kind of slides animations - use [SwiperJS](https://swiperjs.com/get-started).
The lib is included in the project and ready for use. Test with `window.Swiper` in browser console.
# Summary
## Short Video Review
Check the [Video Guide](https://www.loom.com/share/1c707a4ea14e48b7a35a49d7b0a6f1e0)
> PRO TIP
> Use x2 speed in the player 😜
## Testing ✅
### Development Toolbar ✔️
Use development toolbar to switch between data sources.
### Hover/Focus States ✔️
Make sure all "clickable" elements have `&:hover` & `&:focus` states in CSS rules.
This might be related to links, buttons or any other interactive elements.
### Responsiveness ✔️
Make sure the layout is rendered correctly on all standard breakpoint size:
1. 1920px in width...
2. 1680px
3. 1440px
4. 1360px
5. 1280px
6. 1024px
7. 980px
8. 768px
9. 600px
10. 414px
11. 375px
If you follow the rules of REM unit - your layout must be "elastic" and most of the breakpoints should be rendered
properly.
### Pixel Perfect Test ✔️
Compare the final result with provided screenshots.
You can use
available [Browser Extensions](https://chrome.google.com/webstore/detail/perfectpixel-by-welldonec/dkaagdgjmgdmbnecmcefdhjekcoceebi?hl=en)
or any other tool/approach that you're familiar with.
The idea is to have "pretty close" result to requested design.
## Delivery
Once you finished with the task, before letting me know - please review the next [Google Form link](https://forms.gle/w4sJjAyRDSSBRuGLA](https://forms.gle/w4sJjAyRDSSBRuGLA)
If everything is OK - send a Pull Request to the git project or share a ZIP file with me directly.
Generated blocks are including this repository.
This project is running a nodejs script with `browsersync` and `gulp` which improves the development process.
-7
View File
@@ -1,7 +0,0 @@
module.exports = {
mode: "development",
cssUrl: "https://",
blockName: "template",
baseView: "container",
remToPx: 16,
}
-6
View File
@@ -1,6 +0,0 @@
{
"title": "Option Two",
"phrases": "<p><b>Delivering top results to industry leaders:</b></p>",
"cta_text": "Our Success Stories",
"url": "https://google.com"
}
+145
View File
@@ -0,0 +1,145 @@
const path = require('path');
const Generator = require('yeoman-generator');
// const exec = require('child_process').exec;
const baseDir = path.join(__dirname, '../../');
module.exports = class extends Generator {
async prompting() {
this.data = await this.prompt([
{
type: "input",
name: "name",
message: "Block Name",
validate: (str) => {
const matches = str.match(/\d+/g);
if (matches != null) {
return false;
}
return !!str;
}
},
// {
// type: "input",
// name: "name",
// message: "Project ID"
// },
{
type: "list",
name: "baseView",
message: "View Template",
default: 'container',
choices: ['container', 'alignfull'],
},
// {
// type: "confirm",
// name: "include_script",
// default: false,
// message: "Include script.js File?"
// },
]);
}
writing() {
const title = capitalize(this.data.name);
const data = Object.assign(this.data, {
title,
blockFilename: title.toLowerCase().replace(/ /ig, '-'),
blockClassName: title.toLowerCase().replace(/ /ig, '_'),
});
const pathDist = path.join(baseDir, 'blocks', data.blockFilename);
this.fs.copyTpl(
this.templatePath('src/template.template.hbs'),
this.destinationPath(path.join(pathDist, 'src', data.blockFilename + '.template.hbs')),
data
);
this.fs.copyTpl(
this.templatePath('src/styles/template.scss'),
this.destinationPath(path.join(pathDist, 'src', 'styles', data.blockFilename + '.scss')),
data
);
this.fs.copyTpl(
this.templatePath('src/scripts/template.mjs'),
this.destinationPath(path.join(pathDist, 'src', 'scripts', data.blockFilename + '.mjs')),
data
);
this.fs.copyTpl(
this.templatePath('src/images/demo.jpeg'),
this.destinationPath(path.join(pathDist, 'src', 'images', 'demo.jpeg')),
data
);
this.fs.copyTpl(
this.templatePath('config/default.cjs'),
this.destinationPath(path.join(pathDist, 'config', 'default.cjs')),
data
);
this.fs.copyTpl(
this.templatePath('package.json'),
this.destinationPath(path.join(pathDist, 'package.json')),
data
);
this.fs.copyTpl(
this.templatePath('data/default.json'),
this.destinationPath(path.join(pathDist, 'data', 'default.json')),
data
);
this.fs.copyTpl(
this.templatePath('data/advanced.json'),
this.destinationPath(path.join(pathDist, 'data', 'advanced.json')),
data
);
this.fs.copyTpl(
this.templatePath('README.md'),
this.destinationPath(path.join(pathDist, 'README.md')),
data
);
this.fs.copyTpl(
this.templatePath('.editorconfig'),
this.destinationPath(path.join(pathDist, '.editorconfig')),
data
);
this.fs.copyTpl(
this.templatePath('.gitignore'),
this.destinationPath(path.join(pathDist, '.gitignore')),
data
);
// Run BUILD script
// var cmd = exec("npm run build", function (err, stdout, stderr) {
// if (err) {
// console.log('Issue with running - "npm run build"\n\n', err);
// }
// });
// console.log(`\n\nDon't forget to connect the Component in your functions.php file ;)\n\n`);
}
};
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(' ');
}
+23
View File
@@ -0,0 +1,23 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org
# WordPress Coding Standards
# https://make.wordpress.org/core/handbook/coding-standards/
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
[*.json]
indent_style = tab
indent_size = 4
[*.md]
trim_trailing_whitespace = false
+7
View File
@@ -0,0 +1,7 @@
# Basic
.idea
.DS_Store
node_modules
vendor
# Custom
+155
View File
@@ -0,0 +1,155 @@
# Development Setup
Install required modules:
```sh
npm install
```
Run development environment:
```sh
npm start
```
## How it works ⚙️
The project runs `gulp` and `browsersync` beyond the scenes.
Each change in template, styling or script files will reload the page. The idea is to have a comfortable development
environment.
# Block Structure
You will find all the block files in `/src` folder.
```
/src/images/
*.png, *jpg, *.svg
/src/scritps/
*.mjs, *js
/src/styles/
*.scss
/src/*.template.hbs
```
# Block rules
We have a “blocks system”, means you will have to follow strict rules and use listed technologies:
## Template Layout & Data
### Data
You will find multiple `*.json` files in `/data` folder after the first run of `npm start`.
These files are used as data sources in layout. By reviewing these files you can understand what parameters you have and
how the data is stored.
There are multiple data sources since the block can be reused in different situations with different data. We have to
make sure that the block is always rendered properly.
> Don't change or edit these files - use the data as it is!
### Handlebars
[Handlebars](https://handlebarsjs.com/guide/ "What is Handlebars") used as a template engine in the project.
All the template layout must be in a single `*.hbs` file that located in `/src` folder.
> Use the data that is available in `/data` folder.
> Avoid using any kind of "freestyle" input/content. Your template file must contain only HTML tags and Handlebars parameters.
### Static Media Files 🖼️
Use the `/src/images` folder in case you need to upload images or video files to the template.
These files will be available by the next URL: http://localhost:3000/images/${filename}
### Class Naming Convention
Use BEM naming system for class names: http://getbem.com/naming/
## Styling rules 🎨
### Mobile First 📱
Use Mobile First approach. Start with mobile device styling and then focus on other screen sizes by using @media (
min-width: ...px).
### CSS Units
Use `rem` units instead of pixels.
For example, `1rem = 16pixels` depends on project.
No need to use rem in situations of `1px`, `2px` or `3px`. (usually used for borders width).
It's important to mention that the block is "elastic". By using `rem` units we are able to scale the layout and keep the
aspect ratio.
### Global Styling
The development environment includes CSS rules of the original project. This is including fonts, CSS variables,
container logic etc...
The CSS file is already embedded in served HTML.
# JavaScript
## Sliders
For any kind of slides animations - use [SwiperJS](https://swiperjs.com/get-started).
The lib is included in the project and ready for use. Test with `window.Swiper` in browser console.
# Summary
## Short Video Review
Check the [Video Guide](https://www.loom.com/share/1c707a4ea14e48b7a35a49d7b0a6f1e0)
> PRO TIP
> Use x2 speed in the player 😜
## Testing ✅
### Development Toolbar ✔️
Use development toolbar to switch between data sources.
### Hover/Focus States ✔️
Make sure all "clickable" elements have `&:hover` & `&:focus` states in CSS rules.
This might be related to links, buttons or any other interactive elements.
### Responsiveness ✔️
Make sure the layout is rendered correctly on all standard breakpoint size:
1. 1920px in width...
2. 1680px
3. 1440px
4. 1360px
5. 1280px
6. 1024px
7. 980px
8. 768px
9. 600px
10. 414px
11. 375px
If you follow the rules of REM unit - your layout must be "elastic" and most of the breakpoints should be rendered
properly.
### Pixel Perfect Test ✔️
Compare the final result with provided screenshots.
You can use
available [Browser Extensions](https://chrome.google.com/webstore/detail/perfectpixel-by-welldonec/dkaagdgjmgdmbnecmcefdhjekcoceebi?hl=en)
or any other tool/approach that you're familiar with.
The idea is to have "pretty close" result to requested design.
## Delivery
Once you finished with the task, before letting me know - please review the next [Google Form link](https://forms.gle/w4sJjAyRDSSBRuGLA](https://forms.gle/w4sJjAyRDSSBRuGLA)
If everything is OK - send a Pull Request to the git project or share a ZIP file with me directly.
@@ -0,0 +1,5 @@
module.exports = {
cssUrl: "https://",
blockName: "<%= blockFilename %>",
baseView: "<%= baseView %>",
}
@@ -1,6 +1,8 @@
module.exports = {
cssUrl: "https://",
blockName: "template", // snake_case
{
"title": "Option Two",
"content": "<p><b>Delivering top results to industry leaders:</b></p>",
"cta_text": "Our Success Stories",
"url": "https://google.com"
}
/**
@@ -1,6 +1,6 @@
{
"title": "As a Global Salesforce Partner,\n we deliver Service Cloud solutions\n and complex Field Service Management\n in diverse industries worldwide",
"phrases": "<p><b>Delivering top results to industry leaders:</b></p>",
"content": "<p><b>Delivering top results to industry leaders:</b></p>",
"cta_text": "Our Success Stories",
"url": "https://google.com"
}
@@ -1,5 +1,5 @@
{
"name": "template-block",
"name": "<%= blockFilename %>",
"version": "1.0.0",
"scripts": {
"start": "component-dev"

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

@@ -8,10 +8,33 @@
* Start with mobile device styling and then focus on other screen sizes by using @media (min-width: ...px).
*
*/
.template {
padding: 1rem;
.<%= blockClassName %> {
&__header {
// Header Mobile.
@media (min-width: 1024px) {
// Header Desktop.
}
&-heading {
// Child Element.
}
}
&__visual {
&-image {
// Example of BEM usage.
}
}
&__content {
}
&__footer {
}
}
.template__header {
border-bottom: 2px solid green;
}
/*# sourceMappingURL=template.min.css.map */
@@ -1,4 +1,4 @@
<section class="template">
<section class="<%= blockClassName %>">
{{!
Remove Everything Below:
@@ -16,11 +16,11 @@
}
</style>
<header class="template__header">
<h1 class="template__header-heading">Ready!</h1>
<header class="<%= blockClassName %>__header">
<h1 class="<%= blockClassName %>__header-heading">Ready!</h1>
</header>
<div class="template__content">
<div class="<%= blockClassName %>__content">
<p>
Review the `/data` folder with JSON data files.<br>
Don't change data JSON files - use the data as it is.
+13966 -27
View File
File diff suppressed because it is too large Load Diff
+8 -5
View File
@@ -1,9 +1,10 @@
{
"name": "create-block-dev-tool",
"version": "1.0.1",
"version": "1.0.2",
"scripts": {
"start": "component-dev",
"dev": "NODE_ENV=development node server.js"
"dev": "NODE_ENV=development node server.js",
"generate-block": "yo ./generators/block/index.cjs"
},
"license": "ISC",
"main": "server.js",
@@ -15,12 +16,14 @@
"express-handlebars": "^6.0.4",
"fs-extra": "^10.0.1",
"gulp": "^4.0.2",
"gulp-rename": "^2.0.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-babel": "^8.0.0",
"gulp-rename": "^2.0.0",
"gulp-sass": "^5.1.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-uglify": "^3.0.2",
"sass": "^1.50.1"
"sass": "^1.50.1",
"yeoman-generator": "^5.6.1",
"yo": "^4.3.0"
},
"bin": {
"component-dev": "./server.js"
+1 -5
View File
@@ -161,10 +161,6 @@ function prepareListOfDataFiles(dataFiles) {
}
// TODO:
//
// [v] Add Gulp for CSS/JS Styling
// [v] Add Browsersync that will refresh the page on changes
//
// Breakpoints and data options will come from backend server.
// - Top Panel with options to switch data (select input)
// [v] Top Panel with options to switch data (select input)
// - Options to resize the page and test Responsiveness (select input)
-2
View File
@@ -1,2 +0,0 @@
!function(o){console.log("Ready!"),console.log("jQuery =",o),console.log("Swiper =",window.Swiper)}(window.jQuery);
//# sourceMappingURL=template.min.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["scripts/template.mjs"],"names":["$","console","log","window","Swiper","jQuery"],"mappings":"CAAA,SAAWA,GAETC,QAAQC,IAAI,UACZD,QAAQC,IAAI,WAAYF,GACxBC,QAAQC,IAAI,WAAYC,OAAOC,QAJjC,CAMGD,OAAOE","file":"template.min.js","sourcesContent":["(function ($) {\n\n console.log('Ready!');\n console.log('jQuery =', $);\n console.log('Swiper =', window.Swiper);\n\n})(window.jQuery);\n"]}
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["styles/template.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA;EACE;;AAwBA;EACE","file":"template.min.css","sourcesContent":["/**\n * Use \"rem\" instead of pixels. 1rem = 16pixels\n * No need to use rem in situations of \"1px\". (usually used for borders width).\n *\n * Use BEM naming system for class names: http://getbem.com/naming/\n *\n * Use Mobile First approach.\n * Start with mobile device styling and then focus on other screen sizes by using @media (min-width: ...px).\n *\n */\n\n.template {\n padding: 1rem;\n\n // EXAMPLE OF BREAKPOINTS\n\n @media (min-width: 600px) {\n // Tablet\n }\n\n @media (min-width: 980px) {\n // Large Tablet\n }\n\n @media (min-width: 1024px) {\n // Laptop & Tablet\n }\n\n @media (min-width: 1336px) {\n // Laptop\n }\n\n @media (min-width: 1680px) {\n // Desktop\n }\n\n &__header {\n border-bottom: 2px solid green;\n\n &-heading {\n // Heading\n }\n }\n\n &__content {\n // Content\n }\n}"]}
-48
View File
@@ -1,48 +0,0 @@
/**
* Use "rem" instead of pixels. 1rem = 16pixels
* No need to use rem in situations of "1px". (usually used for borders width).
*
* Use BEM naming system for class names: http://getbem.com/naming/
*
* Use Mobile First approach.
* Start with mobile device styling and then focus on other screen sizes by using @media (min-width: ...px).
*
*/
.template {
padding: 1rem;
// EXAMPLE OF BREAKPOINTS
@media (min-width: 600px) {
// Tablet
}
@media (min-width: 980px) {
// Large Tablet
}
@media (min-width: 1024px) {
// Laptop & Tablet
}
@media (min-width: 1336px) {
// Laptop
}
@media (min-width: 1680px) {
// Desktop
}
&__header {
border-bottom: 2px solid green;
&-heading {
// Heading
}
}
&__content {
// Content
}
}