Browse Source

Add block generator logic.

Now we are able to generate new blocks with yeoman.
pull/1/head v1.0.2
Roman Axelrod 4 years ago
parent
commit
82362b3ab2
  1. 1
      .gitignore
  2. 157
      README.md
  3. 7
      config/development.cjs
  4. 6
      data/two.json
  5. 145
      generators/block/index.cjs
  6. 23
      generators/block/templates/.editorconfig
  7. 7
      generators/block/templates/.gitignore
  8. 155
      generators/block/templates/README.md
  9. 5
      generators/block/templates/config/default.cjs
  10. 8
      generators/block/templates/data/advanced.json
  11. 2
      generators/block/templates/data/default.json
  12. 2
      generators/block/templates/package.json
  13. 0
      generators/block/templates/src/images/demo.jpeg
  14. 0
      generators/block/templates/src/scripts/template.mjs
  15. 35
      generators/block/templates/src/styles/template.scss
  16. 8
      generators/block/templates/src/template.template.hbs
  17. 38377
      package-lock.json
  18. 55
      package.json
  19. 6
      server.js
  20. 2
      src/scripts/template.min.js
  21. 1
      src/scripts/template.min.js.map
  22. 1
      src/styles/template.min.css.map
  23. 48
      src/styles/template.scss

1
.gitignore

@ -9,3 +9,4 @@ deploy.sh
deploy-*.sh deploy-*.sh
# Custom # Custom
blocks

157
README.md

@ -1,155 +1,22 @@
# Development Setup # Create Block - Development Tool
Install required modules: This project used as:
```sh 1. Block generator
npm install 2. Development Environment
```
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 ## Block Generator
You will find all the block files in `/src` folder. To create/generate new block by template use:
``` ```
/src/images/ npm run generate-block
*.png, *jpg, *.svg
/src/scritps/
*.mjs, *js
/src/styles/
*.scss
/src/*.template.hbs
``` ```
# Block rules The `/blocks` folder will be generated. Then you can run `npm install`, `npm start` to launch the development
environment.
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 ## Development Environment
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
config/development.cjs

@ -1,7 +0,0 @@
module.exports = {
mode: "development",
cssUrl: "https://",
blockName: "template",
baseView: "container",
remToPx: 16,
}

6
data/two.json

@ -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
generators/block/index.cjs

@ -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
generators/block/templates/.editorconfig

@ -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
generators/block/templates/.gitignore

@ -0,0 +1,7 @@
# Basic
.idea
.DS_Store
node_modules
vendor
# Custom

155
generators/block/templates/README.md

@ -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.

5
generators/block/templates/config/default.cjs

@ -0,0 +1,5 @@
module.exports = {
cssUrl: "https://",
blockName: "<%= blockFilename %>",
baseView: "<%= baseView %>",
}

8
config/default.cjs → generators/block/templates/data/advanced.json

@ -1,6 +1,8 @@
module.exports = { {
cssUrl: "https://", "title": "Option Two",
blockName: "template", // snake_case "content": "<p><b>Delivering top results to industry leaders:</b></p>",
"cta_text": "Our Success Stories",
"url": "https://google.com"
} }
/** /**

2
data/default.json → generators/block/templates/data/default.json

@ -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", "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", "cta_text": "Our Success Stories",
"url": "https://google.com" "url": "https://google.com"
} }

2
package-template.json → generators/block/templates/package.json

@ -1,5 +1,5 @@
{ {
"name": "template-block", "name": "<%= blockFilename %>",
"version": "1.0.0", "version": "1.0.0",
"scripts": { "scripts": {
"start": "component-dev" "start": "component-dev"

0
src/images/demo.jpeg → generators/block/templates/src/images/demo.jpeg

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

0
src/scripts/template.mjs → generators/block/templates/src/scripts/template.mjs

35
src/styles/template.min.css → generators/block/templates/src/styles/template.scss

@ -8,10 +8,33 @@
* Start with mobile device styling and then focus on other screen sizes by using @media (min-width: ...px). * 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 */

8
src/template.template.hbs → generators/block/templates/src/template.template.hbs

@ -1,4 +1,4 @@
<section class="template"> <section class="<%= blockClassName %>">
{{! {{!
Remove Everything Below: Remove Everything Below:
@ -16,11 +16,11 @@
} }
</style> </style>
<header class="template__header"> <header class="<%= blockClassName %>__header">
<h1 class="template__header-heading">Ready!</h1> <h1 class="<%= blockClassName %>__header-heading">Ready!</h1>
</header> </header>
<div class="template__content"> <div class="<%= blockClassName %>__content">
<p> <p>
Review the `/data` folder with JSON data files.<br> Review the `/data` folder with JSON data files.<br>
Don't change data JSON files - use the data as it is. Don't change data JSON files - use the data as it is.

38377
package-lock.json

File diff suppressed because it is too large

55
package.json

@ -1,28 +1,31 @@
{ {
"name": "create-block-dev-tool", "name": "create-block-dev-tool",
"version": "1.0.1", "version": "1.0.2",
"scripts": { "scripts": {
"start": "component-dev", "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", "license": "ISC",
"type": "module", "main": "server.js",
"dependencies": { "type": "module",
"browser-sync": "^2.27.9", "dependencies": {
"config": "^3.3.7", "browser-sync": "^2.27.9",
"express": "^4.17.3", "config": "^3.3.7",
"express-handlebars": "^6.0.4", "express": "^4.17.3",
"fs-extra": "^10.0.1", "express-handlebars": "^6.0.4",
"gulp": "^4.0.2", "fs-extra": "^10.0.1",
"gulp-rename": "^2.0.0", "gulp": "^4.0.2",
"gulp-sourcemaps": "^3.0.0", "gulp-babel": "^8.0.0",
"gulp-babel": "^8.0.0", "gulp-rename": "^2.0.0",
"gulp-sass": "^5.1.0", "gulp-sass": "^5.1.0",
"gulp-uglify": "^3.0.2", "gulp-sourcemaps": "^3.0.0",
"sass": "^1.50.1" "gulp-uglify": "^3.0.2",
}, "sass": "^1.50.1",
"bin": { "yeoman-generator": "^5.6.1",
"component-dev": "./server.js" "yo": "^4.3.0"
} },
"bin": {
"component-dev": "./server.js"
}
} }

6
server.js

@ -161,10 +161,6 @@ function prepareListOfDataFiles(dataFiles) {
} }
// TODO: // 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. // 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) // - Options to resize the page and test Responsiveness (select input)

2
src/scripts/template.min.js

@ -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
src/scripts/template.min.js.map

@ -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
src/styles/template.min.css.map

@ -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
src/styles/template.scss

@ -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
}
}
Loading…
Cancel
Save