├── app ├── templates │ ├── base │ │ ├── gitkeep │ │ ├── editorconfig │ │ ├── tern-project.json.ejs │ │ ├── LICENSE │ │ ├── package.json.ejs │ │ ├── webpack.config.js │ │ └── README.md.ejs │ ├── styles │ │ ├── main │ │ │ ├── _mixins.scss │ │ │ ├── _variables.scss │ │ │ ├── screens │ │ │ │ ├── _base.scss │ │ │ │ └── _screen.scss │ │ │ ├── components │ │ │ │ ├── _forms.scss │ │ │ │ └── _buttons.scss │ │ │ └── main.scss │ │ └── vendor │ │ │ ├── vendor.scss │ │ │ └── _reset.scss │ ├── git │ │ ├── gitattributes │ │ └── gitignore │ ├── webpack │ │ ├── developmentPlugins.js │ │ ├── debugPlugins.js │ │ ├── paths.js │ │ ├── productionPlugins.js │ │ └── commonPlugins.js │ ├── markup │ │ ├── pug │ │ │ ├── layouts │ │ │ │ ├── general │ │ │ │ │ ├── footer.pug │ │ │ │ │ └── menu.pug │ │ │ │ ├── includes │ │ │ │ │ └── mixins.pug │ │ │ │ └── layout-primary.pug.ejs │ │ │ └── _screen.pug │ │ └── _screen.html.ejs │ ├── assets │ │ ├── head │ │ │ ├── favico.ico │ │ │ ├── favicon.png │ │ │ └── manifest.json.ejs │ │ ├── images │ │ │ └── logo.png │ │ └── icons │ │ │ └── react.svg │ ├── gulp │ │ ├── common │ │ │ ├── fonts.js │ │ │ ├── cssModulesWrite.js │ │ │ ├── scripts.js │ │ │ ├── static.js.ejs │ │ │ ├── styles.js │ │ │ └── markup.js.ejs │ │ ├── production │ │ │ ├── purify.js │ │ │ ├── minifyStyles.js │ │ │ ├── zip.js │ │ │ └── styles-production.js │ │ ├── development │ │ │ ├── serve.js │ │ │ └── watch.js.ejs │ │ ├── gulpfile.js.ejs │ │ └── config.js.ejs │ └── scripts │ │ ├── index.js.ejs │ │ ├── framework.js.ejs │ │ └── app.js ├── filesToAssert.js └── index.js ├── .gitattributes ├── .gitlab-ci.yml ├── .gitignore ├── .travis.yml ├── .babelrc ├── .editorconfig ├── test ├── jquery.js ├── scripts.js ├── foundation.js ├── general.js ├── scss.js ├── bootstrap.js └── markup.js ├── LICENSE ├── docs └── running_the_generator.md ├── package.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md └── README.md /app/templates/base/gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /app/templates/styles/main/_mixins.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/templates/styles/main/_variables.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/templates/git/gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /app/templates/styles/main/screens/_base.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/templates/webpack/developmentPlugins.js: -------------------------------------------------------------------------------- 1 | module.exports = [] 2 | -------------------------------------------------------------------------------- /app/templates/markup/pug/layouts/general/footer.pug: -------------------------------------------------------------------------------- 1 | //- Replace this with the footer 2 | -------------------------------------------------------------------------------- /app/templates/markup/pug/layouts/general/menu.pug: -------------------------------------------------------------------------------- 1 | //- replace this for a menu :) 2 | -------------------------------------------------------------------------------- /app/templates/styles/main/screens/_screen.scss: -------------------------------------------------------------------------------- 1 | // 2 | // <%=projectName%> 3 | // Screen <%= screenNumber %> 4 | // 5 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | test: 2 | image: pixel2html/node-npm-cache:8 3 | script: 4 | - npm install 5 | - npm test 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .tmp 4 | bower_components 5 | demo 6 | test/temp 7 | yarn.lock 8 | package-lock.json 9 | -------------------------------------------------------------------------------- /app/templates/assets/head/favico.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixel2HTML/pixel2html-generator/HEAD/app/templates/assets/head/favico.ico -------------------------------------------------------------------------------- /app/templates/assets/head/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixel2HTML/pixel2html-generator/HEAD/app/templates/assets/head/favicon.png -------------------------------------------------------------------------------- /app/templates/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pixel2HTML/pixel2html-generator/HEAD/app/templates/assets/images/logo.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: node_js 4 | node_js: 5 | - "6.9.0" 6 | 7 | cache: 8 | directories: 9 | - node_modules 10 | -------------------------------------------------------------------------------- /app/templates/assets/head/manifest.json.ejs: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "<%= projectName %>", 3 | "name": "<%= projectName %>", 4 | "start_url": "index.html" 5 | } 6 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", 4 | { 5 | "targets": { 6 | "node": 6, 7 | "uglify": 2 8 | } 9 | }] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /app/templates/webpack/debugPlugins.js: -------------------------------------------------------------------------------- 1 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 2 | 3 | const debugPlugins = [ 4 | new BundleAnalyzerPlugin() 5 | ] 6 | 7 | module.exports = debugPlugins 8 | -------------------------------------------------------------------------------- /app/templates/styles/main/components/_forms.scss: -------------------------------------------------------------------------------- 1 | input[type="text"], 2 | input[type="email"], 3 | input[type="url"], 4 | input[type="password"], 5 | input[type="search"], 6 | textarea { 7 | 8 | &:focus { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/templates/gulp/common/fonts.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const config = require('../config') 3 | 4 | gulp.task('fonts', () => 5 | gulp.src(config.project.fontFiles) 6 | .pipe(gulp.dest(config.directories.dist.fonts)) 7 | ) 8 | -------------------------------------------------------------------------------- /app/templates/styles/main/components/_buttons.scss: -------------------------------------------------------------------------------- 1 | button, 2 | input[type="button"], 3 | input[type="reset"], 4 | input[type="submit"] { 5 | 6 | &:hover { 7 | 8 | } 9 | 10 | &:active, 11 | &:focus { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /app/templates/base/editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /app/templates/scripts/index.js.ejs: -------------------------------------------------------------------------------- 1 | <% if (frontEndFramework) { -%> 2 | // Start frontEndFramework 3 | import './framework' 4 | <% } -%> 5 | 6 | // Here we are importing the whole app 7 | // read more about modules here: 8 | // http://wesbos.com/javascript-modules/ 9 | import './app' 10 | -------------------------------------------------------------------------------- /app/templates/markup/pug/_screen.pug: -------------------------------------------------------------------------------- 1 | extends layouts/layout-primary 2 | 3 | block content 4 | section.delete-all-of-this-to-begin 5 | h1 <%= projectName %> - Screen <%= screenNumber %> 6 | p Welcome to our lovely Pixel2Html Generator. 7 | p Please go ahead and remove this from the partial file and go and hack along 8 | -------------------------------------------------------------------------------- /app/templates/gulp/common/cssModulesWrite.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const config = require('../config') 3 | const fs = require('fs-path') 4 | const getJSON = require('@pixel2html/pipes').getJSON 5 | 6 | gulp.task('writeModules', done => { 7 | const json = getJSON() 8 | fs.writeFileSync(config.directories.src.cssModules, json) 9 | done() 10 | }) 11 | -------------------------------------------------------------------------------- /app/templates/gulp/production/purify.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const config = require('../config') 3 | const purify = require('@pixel2html/pipes').purify 4 | 5 | gulp.task('purify', () => 6 | gulp.src(config.directories.dist.styles + '*.css') 7 | .pipe(purify({paths: config.purify})()) 8 | .pipe(gulp.dest(config.directories.dist.styles)) 9 | ) 10 | -------------------------------------------------------------------------------- /app/templates/gulp/production/minifyStyles.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const minifyStyles = require('@pixel2html/pipes').minifyStyles 3 | const config = require('../config') 4 | 5 | gulp.task('minifyStyles', () => 6 | gulp.src(config.directories.dist.styles + '/*.css') 7 | .pipe(minifyStyles()()) 8 | .pipe(gulp.dest(config.directories.dist.styles)) 9 | ) 10 | -------------------------------------------------------------------------------- /app/templates/webpack/paths.js: -------------------------------------------------------------------------------- 1 | const {cwd} = require('process') 2 | const {join} = require('path') 3 | const config = require('../gulp/config') 4 | 5 | const c = cwd() 6 | 7 | module.exports = { 8 | src: join(c, config.directories.src.base), 9 | entry: join(c, config.project.jsMainFile), 10 | output: join(c, config.directories.dist.scripts), 11 | styles: join(c, config.directories.src.cssModules) 12 | } 13 | -------------------------------------------------------------------------------- /app/templates/gulp/common/scripts.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const webpack = require('webpack') 3 | const webpackConfig = require('../../webpack.config') 4 | 5 | gulp.task('scripts', () => 6 | new Promise(resolve => webpack(webpackConfig, (err, stats) => { 7 | if (err) console.log('Webpack', err) 8 | console.log(stats.toString({ 9 | chunks: false, 10 | colors: true 11 | })) 12 | resolve() 13 | })) 14 | ) 15 | -------------------------------------------------------------------------------- /app/templates/scripts/framework.js.ejs: -------------------------------------------------------------------------------- 1 | <% if (frontEndFramework === 'bootstrap-4') { -%> 2 | // Start Bootstrap 4 3 | import 'bootstrap' 4 | <% } -%> 5 | <% if (frontEndFramework === 'bootstrap-3') { -%> 6 | // Start Bootstrap 3 7 | require('bootstrap-sass') 8 | <% } -%> 9 | <% if (frontEndFramework === 'foundation') { -%> 10 | // Start foundation 11 | import $ from 'jquery' 12 | import 'foundation-sites' 13 | $(document).foundation() 14 | <% } -%> 15 | -------------------------------------------------------------------------------- /app/templates/gulp/production/zip.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const config = require('../config') 3 | const zip = require('gulp-zip') 4 | 5 | gulp.task('zip', () => { 6 | const distFiles = [ 7 | `${config.directories.dist.base}/**`, 8 | `!${config.directories.dist.base}` 9 | ] 10 | 11 | return gulp.src(distFiles, {base: '.'}) 12 | .pipe(zip('latest.zip')).on('error', config.onError) 13 | .pipe(gulp.dest('dist/releases')) 14 | }) 15 | -------------------------------------------------------------------------------- /app/templates/webpack/productionPlugins.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin') 3 | 4 | const productionPlugins = [ 5 | new webpack.optimize.ModuleConcatenationPlugin(), 6 | new webpack.DefinePlugin({ 7 | 'process.env': { 8 | 'NODE_ENV': JSON.stringify('production') 9 | } 10 | }), 11 | new UglifyJSPlugin({sourceMap: true}) 12 | ] 13 | 14 | module.exports = productionPlugins 15 | -------------------------------------------------------------------------------- /app/templates/markup/pug/layouts/includes/mixins.pug: -------------------------------------------------------------------------------- 1 | //- In honor of loved hyperscript daddy of React and Friends 2 | //- https://github.com/hyperhype/hyperscript 3 | mixin h(htmlElement, module) 4 | #{htmlElement}(css-module=module) 5 | if block 6 | block 7 | 8 | //- Thanks WesBos! 9 | mixin svg(filename) 10 | !=icon(filename) 11 | 12 | mixin img(name, module, alt) 13 | img(src=`assets/images/${name}` css-module=module alt= alt ? alt : 'An image') 14 | -------------------------------------------------------------------------------- /app/templates/styles/vendor/vendor.scss: -------------------------------------------------------------------------------- 1 | // 2 | // <%=projectName%> 3 | // 4 | <% if(frontEndFramework === 'bootstrap-4'){ %> 5 | @import "bootstrap/scss/bootstrap.scss"; 6 | <% } %> 7 | <% if(frontEndFramework === 'bootstrap-3'){ %> 8 | @import "bootstrap-sass"; 9 | <% } %> 10 | <% if(frontEndFramework === 'foundation'){ %> 11 | @import "foundation-sites/scss/foundation"; 12 | @include foundation-everything; 13 | <% } %> 14 | <% if(!frontEndFramework){ %> 15 | @import "reset"; 16 | <% } %> 17 | -------------------------------------------------------------------------------- /app/templates/git/gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .tmp 4 | bower_components 5 | node_modules 6 | 7 | # Ignore CSS Modules JSON files 8 | src/assets/cssModules 9 | 10 | _gh_pages 11 | _site 12 | *.diff 13 | *.err 14 | *.orig 15 | *.log 16 | *.rej 17 | *.swo 18 | *.swp 19 | *.zip 20 | *.vi 21 | *~ 22 | .DS_Store 23 | ._* 24 | Thumbs.db 25 | .cache 26 | .project 27 | .settings 28 | .tmproj 29 | *.esproj 30 | nbproject 31 | *.sublime-project 32 | *.sublime-workspace 33 | .idea 34 | .sass-cache 35 | .tmp 36 | iTermocil.yml 37 | .tmuxinator 38 | 39 | /releases/* 40 | -------------------------------------------------------------------------------- /app/templates/styles/main/main.scss: -------------------------------------------------------------------------------- 1 | // 2 | // <%=projectName%> 3 | // 4 | @import 'variables'; 5 | @import 'mixins'; 6 | 7 | // We can use CSS modules 8 | // but for now its disabled 9 | // make sure your css is inside this :global 10 | // Happy Styling! Pixel2HTML 11 | :global { 12 | // screens:start 13 | @import 'screens/_base'; 14 | <% for(var i=1; i<=qtyScreens; i++) {%> 15 | @import 'screens/screen_<%=i%>';<% } %> 16 | // screens:end 17 | 18 | // components:start 19 | @import 'components/_forms'; 20 | @import 'components/_buttons'; 21 | // components:end 22 | } 23 | -------------------------------------------------------------------------------- /app/templates/scripts/app.js: -------------------------------------------------------------------------------- 1 | // Welcome to our main file! 2 | // we are using Webpack and ES6 3 | // feel free to use imports and exports 4 | // as well as ES6 code 5 | 6 | // Try to make your whole code work via exporting 7 | // a single function to get Hot Module Replacement 8 | // just like app.init() 9 | // from the good ol'days 10 | 11 | const colors = [ 'pink', 'red', 'blue' ] 12 | const moColors = ['yellow', 'papayawhip'] 13 | 14 | const allTheColors = [ ...colors, ...moColors ] 15 | allTheColors.map(color => console.log(`The color is ${color}`)) 16 | 17 | // Happy coding from Pixel2HTML 18 | -------------------------------------------------------------------------------- /app/templates/base/tern-project.json.ejs: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaVersion": 6, 3 | "libs": [ 4 | "browser" 5 | <% if(jQuery || frontEndFramework){ -%> 6 | ,"jquery" 7 | <% } -%> 8 | ], 9 | "loadEagerly": [], 10 | "dontLoad": [ 11 | "node_modules/**" 12 | ], 13 | "plugins": { 14 | "doc_comment": true, 15 | "node": { 16 | "dontLoad": "", 17 | "load": "", 18 | "modules": "" 19 | }, 20 | "node_resolve": {}, 21 | "es_modules": {}, 22 | "modules": { 23 | "dontLoad": "", 24 | "load": "", 25 | "modules": "" 26 | }, 27 | "commonjs": {} 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/templates/webpack/commonPlugins.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | 3 | let common = [ 4 | // Split vendor packages coming from npm 5 | new webpack.optimize.CommonsChunkPlugin({ 6 | name: 'vendor', 7 | minChunks: module => /node_modules/.test(module.resource) 8 | }), 9 | // Allow everyone to use jQuery like it was global 10 | new webpack.ProvidePlugin({ 11 | $: 'jquery', 12 | jQuery: 'jquery', 13 | 'window.jQuery': 'jquery', 14 | // Popper is for Bootstrap 4 mainly 15 | Popper: ['popper.js', 'default'] 16 | }), 17 | // Do NOT import the BLOAT from moment.js 18 | // thanks create-react-app 19 | new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) 20 | ] 21 | 22 | module.exports = common 23 | -------------------------------------------------------------------------------- /app/templates/gulp/common/static.js.ejs: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const config = require('../config') 3 | const del = require('del') 4 | 5 | gulp.task('clean', () => 6 | del([ 7 | config.directories.dist.base, 8 | config.directories.src.cssModules 9 | ]) 10 | ) 11 | 12 | gulp.task('images', () => 13 | gulp.src(config.directories.src.images + '/**/*') 14 | .pipe(gulp.dest(config.directories.dist.images)) 15 | ) 16 | <% if(markupLanguage === 'html'){ -%> 17 | gulp.task('icons', () => 18 | gulp.src(config.directories.src.icons + '/**/*') 19 | .pipe(gulp.dest(config.directories.dist.icons)) 20 | )<% } -%> 21 | 22 | gulp.task('head', () => 23 | gulp.src(config.directories.src.base + '/assets/head/**/*') 24 | .pipe(gulp.dest(config.directories.dist.base + '/assets/head')) 25 | ) 26 | -------------------------------------------------------------------------------- /app/templates/gulp/production/styles-production.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const config = require('../config') 3 | const styles = require('@pixel2html/pipes').styles 4 | 5 | gulp.task('main:styles:prod', () => 6 | gulp.src(config.project.cssFiles) 7 | .pipe(styles({ 8 | modules: true, 9 | name: 'main.css', 10 | production: config.production 11 | })()) 12 | .pipe(gulp.dest(config.directories.dist.styles)) 13 | ) 14 | 15 | gulp.task('vendor:styles:prod', () => 16 | gulp.src(config.project.cssVendorFile) 17 | .pipe(styles({ 18 | modules: false, 19 | name: 'vendor.css', 20 | production: config.production 21 | })()) 22 | .pipe(gulp.dest(config.directories.dist.styles)) 23 | ) 24 | 25 | gulp.task('styles:prod', gulp.series('main:styles:prod', 'vendor:styles:prod', 'writeModules')) 26 | -------------------------------------------------------------------------------- /test/jquery.js: -------------------------------------------------------------------------------- 1 | import helpers from 'yeoman-test' 2 | import assert from 'yeoman-assert' 3 | import path from 'path' 4 | 5 | describe('jQuery features', function () { 6 | beforeEach(function () { 7 | return helpers.run(path.join(__dirname, '../app')) 8 | .withOptions({ 9 | 'skip-install': true 10 | }) 11 | .withPrompts({ 12 | projectName: 'Pixel2HTML', 13 | qtyScreens: 3, 14 | markupLanguage: 'html', 15 | frontEndFramework: 'bootstrap-4', 16 | jQuery: true 17 | }) 18 | .toPromise() 19 | }) 20 | 21 | it('should list dependencies in package.json', function () { 22 | assert.fileContent('package.json', /"jquery"/) 23 | }) 24 | 25 | it('should exists a gulp routine', function () { 26 | assert.file([ 27 | 'gulp/common/scripts.js' 28 | ]) 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /app/templates/gulp/common/styles.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const config = require('../config') 3 | const styles = require('@pixel2html/pipes').styles 4 | 5 | gulp.task('main:styles', () => 6 | gulp.src(config.project.cssFiles) 7 | .pipe(styles({ 8 | modules: true, 9 | name: 'main.css', 10 | production: config.production 11 | })()) 12 | .on('error', config.onError) 13 | .pipe(gulp.dest(config.directories.dist.styles)) 14 | ) 15 | 16 | gulp.task('vendor:styles', () => 17 | gulp.src(config.project.cssVendorFile) 18 | .pipe(styles({ 19 | modules: false, 20 | name: 'vendor.css', 21 | production: config.production 22 | })()) 23 | .on('error', config.onError) 24 | .pipe(gulp.dest(config.directories.dist.styles)) 25 | ) 26 | 27 | gulp.task('styles', gulp.series('main:styles', 'vendor:styles', 'writeModules')) 28 | -------------------------------------------------------------------------------- /app/templates/gulp/development/serve.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const config = require('../config') 3 | const browserSync = require('browser-sync') 4 | const openBrowser = require('react-dev-utils/openBrowser') 5 | const WebpackDevServerUtils = require('react-dev-utils/WebpackDevServerUtils') 6 | const {prepareUrls, choosePort} = WebpackDevServerUtils 7 | 8 | gulp.task('browser-sync', done => { 9 | const DEFAULT_PORT = 3000 10 | const HOST = '0.0.0.0' 11 | const protocol = 'http' 12 | choosePort(HOST, DEFAULT_PORT) 13 | .then(port => { 14 | if (port === null) return 15 | const urls = prepareUrls(protocol, HOST, port) 16 | browserSync.init({ 17 | port, 18 | server: { 19 | baseDir: config.directories.dist.base, 20 | serveStaticOptions: { 21 | extensions: ['html'] 22 | } 23 | }, 24 | open: false, 25 | logConnections: true, 26 | tunnel: config.tunnel, 27 | logPrefix: 'Pixel2Html', 28 | files: ['**/*.css'] 29 | }) 30 | openBrowser(urls.localUrlForBrowser) 31 | done() 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2018, Pixel2HTML. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/templates/base/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017, Pixel2HTML. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/templates/gulp/development/watch.js.ejs: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const browserSync = require('browser-sync') 3 | const config = require('../config') 4 | 5 | const reload = done => { 6 | browserSync.reload() 7 | done() 8 | } 9 | 10 | gulp.task('watch', done => { 11 | // static files 12 | gulp.watch(config.directories.src.markup+'/**/*.<%=markupLanguage%>', gulp.series( 'markup', reload )) 13 | <% if (markupLanguage === 'pug') { -%> 14 | gulp.watch(config.directories.src.icons+'/**/*.svg', gulp.series( 'markup', reload )) 15 | <% } else { -%> 16 | gulp.watch(config.directories.src.icons+'/**/*.svg', gulp.series( 'icons', reload )) 17 | <% } -%> 18 | gulp.watch(config.directories.src.images+'/**/*', gulp.series( 'images', reload )) 19 | gulp.watch(config.directories.src.base + '/assets/head/**/*', gulp.series('head', reload)) 20 | // Fonts 21 | gulp.watch(config.project.fontFiles, gulp.series('fonts', reload)) 22 | //styles 23 | gulp.watch(config.directories.src.styles + '/**/*.scss', gulp.series('styles')) 24 | // Scripts 25 | gulp.watch(config.directories.src.scripts + '/**/*.js', gulp.series('scripts', reload)) 26 | done() 27 | }) 28 | -------------------------------------------------------------------------------- /test/scripts.js: -------------------------------------------------------------------------------- 1 | import helpers from 'yeoman-test' 2 | import assert from 'yeoman-assert' 3 | import path from 'path' 4 | 5 | describe('Script features', function () { 6 | beforeEach(function () { 7 | return helpers.run(path.join(__dirname, '../app')) 8 | .withOptions({ 9 | 'skip-install': true 10 | }) 11 | .withPrompts({ 12 | projectName: 'Pixel2HTML', 13 | qtyScreens: 3, 14 | markupLanguage: 'html', 15 | frontEndFramework: 'bootstrap-4', 16 | jQuery: true 17 | }) 18 | .toPromise() 19 | }) 20 | 21 | it('creates expected base files', function () { 22 | assert.file([ 23 | 'src/assets/js/index.js', 24 | 'src/assets/js/app.js', 25 | 'webpack.config.js', 26 | 'webpack/commonPlugins.js', 27 | 'webpack/debugPlugins.js', 28 | 'webpack/developmentPlugins.js', 29 | 'webpack/paths.js', 30 | 'webpack/productionPlugins.js' 31 | ]) 32 | }) 33 | 34 | it('should exists a gulp routine', function () { 35 | assert.file([ 36 | 'gulp/common/scripts.js' 37 | ]) 38 | }) 39 | 40 | it('should have the project name on package.json', function () { 41 | assert.fileContent('src/assets/js/app.js', /Pixel2HTML/) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /app/templates/gulp/gulpfile.js.ejs: -------------------------------------------------------------------------------- 1 | const config = require('./gulp/config') 2 | const gulp = require('gulp') 3 | const prod = config.production 4 | 5 | const common = [ 6 | 'cssModulesWrite', 7 | 'fonts', 'markup', 8 | 'scripts', 'static', 9 | 'styles' 10 | ] 11 | const development = [ 12 | 'serve', 'watch' 13 | ] 14 | const production = [ 15 | 'minifyStyles', 'purify', 16 | 'styles-production', 'zip' 17 | ] 18 | 19 | common.forEach(file => require(`./gulp/common/${file}`)) 20 | prod 21 | ? production.forEach(file => require(`./gulp/production/${file}`)) 22 | : development.forEach(file => require(`./gulp/development/${file}`)) 23 | 24 | const prodTasks = [ 25 | 'minifyStyles', 26 | 'purify' 27 | ] 28 | 29 | let tasks = [ 30 | 'clean', 31 | config.production ? 'styles:prod' : 'styles', 32 | 'images', 'head', 33 | 'scripts', 'fonts', 34 | 'markup',<% if (markupLanguage === 'html') { %> 'icons',<% } %> 35 | prod && [...prodTasks] 36 | ] 37 | 38 | const filteredTasks = tasks.filter(task => !!task) 39 | gulp.task('build', gulp.series(...filteredTasks)) 40 | 41 | if (prod) { 42 | gulp.task('release', gulp.series('build', 'zip')) 43 | } else { 44 | gulp.task('serve', gulp.parallel('browser-sync', 'watch')) 45 | gulp.task('default', gulp.series('build', 'serve')) 46 | } 47 | -------------------------------------------------------------------------------- /app/templates/markup/_screen.html.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= projectName %> - Screen <%= screenNumber %> 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 🐼🐼🐼🐼 Everything here will be replaced with the compiled CSS 🐼🐼🐼🐼 16 | 17 | 18 | 19 | 20 | 23 | 24 |

<%= projectName %> - Screen <%= screenNumber %>

25 |

Time to code 🐟

26 | 27 | 🐼🐼🐼🐼 Everything here will be replaced 🐼🐼🐼🐼 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/foundation.js: -------------------------------------------------------------------------------- 1 | import helpers from 'yeoman-test' 2 | import assert from 'yeoman-assert' 3 | import path from 'path' 4 | 5 | describe('Foundation features', function () { 6 | beforeEach(function () { 7 | return helpers.run(path.join(__dirname, '../app')) 8 | .withOptions({ 9 | 'skip-install': true 10 | }) 11 | .withPrompts({ 12 | projectName: 'Pixel2HTML', 13 | qtyScreens: 3, 14 | markupLanguage: 'html', 15 | frontEndFramework: 'foundation' 16 | }) 17 | .toPromise() 18 | }) 19 | 20 | it('Should exists dependencies in package.json', function () { 21 | assert.fileContent('package.json', /"foundation-sites"/) 22 | }) 23 | 24 | it('should exists a gulp routine', function () { 25 | assert.file([ 26 | 'gulp/common/styles.js', 27 | 'gulp/common/scripts.js' 28 | ]) 29 | }) 30 | it('should exists vendor files', function () { 31 | assert.file([ 32 | 'src/assets/styles/vendor/vendor.scss', 33 | 'src/assets/js/index.js' 34 | ]) 35 | }) 36 | 37 | it('should include foundation include', function () { 38 | assert.fileContent('src/assets/styles/vendor/vendor.scss', /import "foundation-sites\/scss\/foundation";/) 39 | assert.fileContent('src/assets/js/framework.js', /import 'foundation-sites'/) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /app/filesToAssert.js: -------------------------------------------------------------------------------- 1 | const baseFiles = [ 2 | 'LICENSE', 3 | 'webpack.config.js' 4 | ] 5 | 6 | const baseTemplates = [ 7 | 'package.json', 8 | 'README.md', 9 | ] 10 | 11 | const dotfiles = [ 12 | 'editorconfig', 13 | 'gitignore', 14 | 'gitattributes', 15 | 'project.conf' 16 | ] 17 | 18 | const webpack = [ 19 | 'webpack/commonPlugins.js', 20 | 'webpack/debugPlugins.js', 21 | 'webpack/developmentPlugins.js', 22 | 'webpack/paths.js', 23 | 'webpack/productionPlugins.js', 24 | ] 25 | 26 | const gulpFiles = [ 27 | 'gulp/common/cssModulesWrite.js', 28 | 'gulp/common/fonts.js', 29 | 'gulp/common/scripts.js', 30 | 'gulp/common/styles.js', 31 | 'gulp/development/serve.js', 32 | 'gulp/production/minifyStyles.js', 33 | 'gulp/production/purify.js', 34 | 'gulp/production/styles-production.js', 35 | 'gulp/production/zip.js', 36 | ] 37 | 38 | const gulpTemplates = [ 39 | 'gulpfile.js', 40 | 'gulp/config.js', 41 | 'gulp/common/markup.js', 42 | 'gulp/common/static.js', 43 | 'gulp/development/watch.js', 44 | ] 45 | 46 | const scss = [ 47 | 'styles/main/components/_buttons.scss', 48 | 'styles/main/components/_forms.scss', 49 | 'styles/main/screens/_base.scss', 50 | 'styles/main/_mixins.scss', 51 | 'styles/main/_variables.scss', 52 | 'styles/main/main.scss', 53 | 'styles/vendor/_reset.scss', 54 | 'styles/vendor/vendor.scss', 55 | ] 56 | 57 | module.exports = { 58 | baseFiles, 59 | baseTemplates, 60 | dotfiles, 61 | webpack, 62 | gulpFiles, 63 | gulpTemplates, 64 | scss, 65 | } 66 | -------------------------------------------------------------------------------- /test/general.js: -------------------------------------------------------------------------------- 1 | import helpers from 'yeoman-test' 2 | import assert from 'yeoman-assert' 3 | import path from 'path' 4 | 5 | describe('General Assertions', function () { 6 | beforeEach(function () { 7 | return helpers.run(path.join(__dirname, '../app')) 8 | .withOptions({ 9 | 'skip-install': true 10 | }) 11 | .withPrompts({ 12 | projectName: 'Pixel2HTML', 13 | qtyScreens: 6, 14 | markupLanguage: 'html' 15 | }) 16 | .toPromise() 17 | }) 18 | 19 | it('creates expected base files', function () { 20 | assert.file([ 21 | '.gitignore', 22 | '.gitattributes', 23 | 'package.json', 24 | 'gulpfile.js', 25 | 'package.json', 26 | 'webpack.config.js', 27 | '.tern-project', 28 | '.editorconfig', 29 | 'LICENSE', 30 | 'src/index.html', 31 | 'src/screen-2.html', 32 | 'src/screen-3.html', 33 | 'src/screen-4.html', 34 | 'src/screen-5.html', 35 | 'src/screen-6.html', 36 | 'gulp/config.js', 37 | 'gulp/common/styles.js', 38 | 'gulp/development/watch.js', 39 | 'gulp/development/serve.js', 40 | 'gulp/common/scripts.js', 41 | 'gulp/common/fonts.js', 42 | 'gulp/common/static.js', 43 | 'gulp/common/markup.js', 44 | 'gulp/production/minifyStyles.js', 45 | 'gulp/production/styles-production.js', 46 | 'gulp/production/purify.js', 47 | 'src/assets/head/favico.ico', 48 | 'src/assets/head/favicon.png', 49 | 'src/assets/head/manifest.json' 50 | ]) 51 | }) 52 | 53 | it('should have the project name on package.json', function () { 54 | assert.fileContent('package.json', /"name": "Pixel2HTML"/) 55 | }) 56 | }) 57 | -------------------------------------------------------------------------------- /docs/running_the_generator.md: -------------------------------------------------------------------------------- 1 | # Running the Pixel2HTML Generator 2 | 3 | ### Option 1: Answering the questions 4 | 5 | To generate the **Pixel2HTML Boilerplate** go to your project folder and run this command in your shell 6 | 7 | ``` 8 | $ cd ~/your/project/folder 9 | $ yo pixel2html 10 | ``` 11 | The **Pixel2HTML Boilerplate** will ask you questions about this points. Answering with the desired options will generate the code. 12 | 13 | * Project Name? 14 | * Quantity of screens? 15 | * Markup Language? _Options: HTML / Pug_ 16 | * Markup Integration? _Options: None / Jekyll_ 17 | * Frontend Framework _Options: None / Bootstrap 3.*/ Bootstrap 4 Beta / Foundation_ 18 | * jQuery? _Options: true / false_ 19 | 20 | 21 | ### Option 2: Using available parameters 22 | 23 | You also can answer this questions passing parameters to the generator command. 24 | 25 | Here there are the available questions: 26 | 27 | * `--projectName` (*string*) 28 | * `--qtyScreens` (*int*) 29 | * `--markupLanguage` (*string*) [html, pug] 30 | * `--markupIntegration` (*string*) [jekyll, none] 31 | * `--frontEndFramework` (*string*) [bootstrap, bootstrap-4, foundation, none] 32 | * `--jQuery` (*bool*) 33 | 34 | Example: 35 | 36 | ``` 37 | $ yo pixel2html --projectName=Floyd --markupLanguage='html' 38 | ``` 39 | 40 | ### Option 3: Using the config file 41 | 42 | You can create a `.project.conf` file in the root directory of your project. 43 | Here an example of it's structure: 44 | 45 | ``` 46 | { 47 | "projectName": 'XXX', 48 | "qtyScreens": 4, 49 | "markupLanguage": 'html', 50 | "markupIntegration": 'jekyll', 51 | "frontEndFramework": "bootstrap", 52 | "jQuery": true 53 | } 54 | ``` 55 | 56 | Once you answered all the question, you can hit at: 57 | ``` 58 | $ yo pixel2html 59 | ``` 60 | -------------------------------------------------------------------------------- /app/templates/markup/pug/layouts/layout-primary.pug.ejs: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang='en') 3 | head 4 | block title 5 | title <%= projectName %> 6 | meta(charset='utf-8') 7 | meta(http-equiv='X-UA-Compatible', content='IE=edge,chrome=1') 8 | meta(name="viewport" content="width=device-width, initial-scale=1") 9 | meta(name='description' content='<%= projectName %> - Scaffolded with Pixel2HTML Frontend Generator') 10 | meta(name='theme-color', content='#3e456c') 11 | link(rel='manifest' href='assets/head/manifest.json') 12 | link(rel="shortcut icon" href="assets/head/favico.ico") 13 | link(rel="icon" type="image/png" href="assets/head/favicon.png") 14 | if production 15 | link(rel='stylesheet', href='assets/css/vendor.min.css') 16 | link(rel='stylesheet', href='assets/css/main.min.css') 17 | else 18 | link(rel='stylesheet', href='assets/css/vendor.css') 19 | link(rel='stylesheet', href='assets/css/main.css') 20 | block head 21 | //- If extra head content is necessary per page, it can be added per screen 22 | 23 | body 24 | include includes/mixins 25 | include general/menu 26 | block content 27 | //- This gets replaced by content per page 28 | 29 | include general/footer 30 | block footer 31 | //- If extra footer content is necessary per page, it can be added per screen 32 | 33 | if production<% if(jQuery || frontEndFramework){ %> 34 | script(src='//code.jquery.com/jquery-3.2.1.min.js')<% } %> 35 | script(src='assets/js/vendor.min.js') 36 | script(src='assets/js/main.min.js') 37 | else 38 | script(src='assets/js/vendor.js') 39 | script(src='assets/js/main.js') 40 | block scripts 41 | //- Also if more scripts are needed you can hook in here <3 42 | -------------------------------------------------------------------------------- /app/templates/gulp/config.js.ejs: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // We use this to read flags in the command line 3 | const argv = require('yargs').argv 4 | // Add your conditions here 💅 5 | const production = !!argv.prod || !!argv.production 6 | const debug = !!argv.debug 7 | const tunnel = !!argv.tunnel 8 | 9 | module.exports = { 10 | directories: { 11 | src: { 12 | base: '<%= paths.src.base %>',<% if(markupLanguage == 'html'){ %> 13 | markup: '<%= paths.src.markup %>',<% } %><% if(markupLanguage == 'pug'){ %> 14 | markup: '<%= paths.src.markup %>/pug',<% } %> 15 | fonts: '<%= paths.src.fonts %>', 16 | icons: '<%= paths.src.icons %>', 17 | images: '<%= paths.src.images %>', 18 | scripts: '<%= paths.src.scripts %>', 19 | styles: '<%= paths.src.styles %>', 20 | cssModules: 'src/assets/cssModules/css.json' 21 | }, 22 | dist: { 23 | base: '<%= paths.dist.base %>', 24 | markup: '<%= paths.dist.markup %>', 25 | fonts: 'dist/assets/fonts', 26 | icons: 'dist/assets/icons', 27 | images: 'dist/assets/images', 28 | scripts: 'dist/assets/js', 29 | styles: 'dist/assets/css', 30 | } 31 | }, 32 | project: { 33 | cssFiles: 'src/assets/styles/main/**/!(_)*.scss', 34 | cssVendorFile: 'src/assets/styles/vendor/vendor.scss', 35 | jsMainFile: 'src/assets/js/index.js', 36 | fontFiles: [ 37 | '<%= paths.src.fonts %>/**/*'<% if(frontEndFramework == 'bootstrap-3'){ %>, 38 | './node_modules/bootstrap-sass/assets/fonts/**/*'<% } %> 39 | ] 40 | }, 41 | onError: function(error) { 42 | console.log(error.toString()) 43 | production 44 | ? process.exit(1) 45 | : this.emit('end') 46 | }, 47 | production, 48 | debug, 49 | tunnel, 50 | // Stuff for PurifyCss 51 | purify: ['./dist/**/*.js', './dist/**/*.html'] 52 | } 53 | -------------------------------------------------------------------------------- /app/templates/base/package.json.ejs: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= projectName %>", 3 | "description": "<%= projectName %> front end source code", 4 | "license": "MIT", 5 | "repository": "http://www.pixel2html.com", 6 | "version": "1.0.0", 7 | "scripts": { 8 | "start": "npm install", 9 | "code": "gulp", 10 | "build": "gulp build --prod", 11 | "release": "gulp release --prod", 12 | "lint:js": "eslint 'src/**/*.js'", 13 | "lint:scss": "stylelint 'src/**/*.scss'", 14 | "lint": "npm run lint:js; npm run lint:scss", 15 | "debug": "gulp scripts --debug" 16 | }, 17 | "dependencies": { 18 | "@babel/core": "^7.0.0-beta.39", 19 | "@babel/runtime": "^7.0.0-beta.39", 20 | "@pixel2html/babel-preset": "^0.8.1", 21 | "@pixel2html/eslint-config": "^1.2.0", 22 | "@pixel2html/pipes": "^2.0.0", 23 | "babel-loader": "8.0.0-beta.0", 24 | "del": "^3.0.0", 25 | "eslint": "^4.17.0", 26 | "eslint-loader": "^1.9.0", 27 | "fs-path": "^0.0.23", 28 | "gulp": "^4.0.0", 29 | <% if(frontEndFramework === 'bootstrap-4'){ -%> 30 | "bootstrap": "^4.0.0", 31 | "popper.js": "^1.12.9", 32 | <% } -%> 33 | <% if(frontEndFramework === 'bootstrap-3'){ -%> 34 | "bootstrap-sass": "^3.3.7", 35 | <% } -%> 36 | <% if(frontEndFramework === 'foundation'){ -%> 37 | "foundation-sites": "^6.4.3", 38 | <% } -%> 39 | <% if(jQuery || frontEndFramework){ -%> 40 | "jquery": "^3.3.1", 41 | <% } -%> 42 | "gulp-zip": "^4.1.0", 43 | "uglifyjs-webpack-plugin": "^1.1.8", 44 | "webpack": "^3.10.0", 45 | "yargs": "^11.0.0" 46 | }, 47 | "devDependencies": { 48 | "@pixel2html/stylelint-config": "^1.3.0", 49 | "browser-sync": "^2.23.6", 50 | "react-dev-utils": "^5.0.0", 51 | "stylelint": "^8.4.0", 52 | "webpack-bundle-analyzer": "^2.10.0" 53 | }, 54 | "stylelint": { 55 | "extends": "@pixel2html/stylelint-config" 56 | }, 57 | "eslintConfig": { 58 | "extends": "@pixel2html/eslint-config" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/templates/gulp/common/markup.js.ejs: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const config = require('../config') 3 | const production = config.production 4 | <% if (markupLanguage === 'pug') { -%> 5 | const fs = require('fs') 6 | const pug = require('@pixel2html/pipes').pug 7 | <% } -%> 8 | <% if (markupLanguage === 'html') { -%> 9 | const html = require('@pixel2html/pipes').html 10 | const BASE = config.directories.dist.base 11 | 12 | // Epic h4xxxxx 13 | const JS_DIR = config.directories.dist.scripts.split(`${BASE}/`)[1] 14 | const CSS_DIR = config.directories.dist.styles.split(`${BASE}/`)[1] 15 | 16 | const JS_EXT = production ? '.min.js' : '.js' 17 | const CSS_EXT = production ? '.min.css' : '.css' 18 | 19 | const js = [ 20 | `${JS_DIR}/vendor${JS_EXT}`, 21 | `${JS_DIR}/main${JS_EXT}` 22 | ] 23 | 24 | if (production) js.unshift('//code.jquery.com/jquery-3.2.1.min.js') 25 | 26 | const css = [ 27 | `${CSS_DIR}/vendor${CSS_EXT}`, 28 | `${CSS_DIR}/main${CSS_EXT}` 29 | ] 30 | <% } -%> 31 | 32 | gulp.task('markup', () => 33 | gulp.src(config.directories.src.markup + '/*.<%=markupLanguage%>') 34 | <% if (markupLanguage === 'pug') { -%> 35 | .pipe(pug({ 36 | pug: { 37 | basedir: config.directories.src.markup, 38 | locals: { 39 | icon: name => fs.readFileSync(`./src/assets/icons/${name}.svg`), 40 | production 41 | } 42 | }, 43 | cssModules: `./${config.directories.src.cssModules}`, 44 | imgAutoSize: { 45 | root: `./${config.directories.dist.base}`, 46 | processEmptySize: true 47 | } 48 | })()) 49 | .on('error', config.onError) 50 | <% } -%> 51 | <% if (markupLanguage === 'html') { -%> 52 | .pipe(html({ 53 | cssModules: `./${config.directories.src.cssModules}`, 54 | imgAutoSize: { 55 | root: `./${config.directories.dist.base}`, 56 | processEmptySize: true 57 | }, 58 | htmlReplace: {js, css} 59 | })()) 60 | .on('error', config.onError) 61 | <% } -%> 62 | .pipe(gulp.dest(config.directories.dist.markup)) 63 | ) 64 | -------------------------------------------------------------------------------- /test/scss.js: -------------------------------------------------------------------------------- 1 | import helpers from 'yeoman-test' 2 | import assert from 'yeoman-assert' 3 | import path from 'path' 4 | 5 | import { scss } from '../app/filesToAssert' 6 | 7 | describe('SCSS features', function () { 8 | beforeEach(function () { 9 | return helpers.run(path.join(__dirname, '../app')) 10 | .withOptions({ 11 | 'skip-install': true 12 | }) 13 | .withPrompts({ 14 | projectName: 'Pixel2HTML', 15 | qtyScreens: 3, 16 | markupLanguage: 'html' 17 | }) 18 | .toPromise() 19 | }) 20 | 21 | it('should exists base SCSS file', function () { 22 | const styles = scss.map(file => `src/assets/${file}`) 23 | assert.file(styles) 24 | }) 25 | 26 | it('should exists screens SCSS files', function () { 27 | assert.file([ 28 | 'src/assets/styles/main/screens/screen_1.scss', 29 | 'src/assets/styles/main/screens/screen_2.scss', 30 | 'src/assets/styles/main/screens/screen_3.scss' 31 | ]) 32 | }) 33 | 34 | it('should have project and client ids on comments', function () { 35 | assert.fileContent('src/assets/styles/main/screens/screen_1.scss', /Pixel2HTML/) 36 | assert.fileContent('src/assets/styles/main/screens/screen_2.scss', /Pixel2HTML/) 37 | assert.fileContent('src/assets/styles/main/screens/screen_3.scss', /Pixel2HTML/) 38 | }) 39 | 40 | it('should have screen number on comments', function () { 41 | assert.fileContent('src/assets/styles/main/screens/screen_1.scss', /Screen 1/) 42 | assert.fileContent('src/assets/styles/main/screens/screen_2.scss', /Screen 2/) 43 | assert.fileContent('src/assets/styles/main/screens/screen_3.scss', /Screen 3/) 44 | }) 45 | 46 | it('should exists a gulp routine', function () { 47 | assert.file([ 48 | 'gulp/common/styles.js', 49 | 'gulp/common/cssModulesWrite.js', 50 | 'gulp/production/minifyStyles.js', 51 | 'gulp/production/purify.js', 52 | 'gulp/production/styles-production.js' 53 | ]) 54 | }) 55 | 56 | it('should exists a pipe in the main:styles routing', function () { 57 | assert.fileContent('gulp/common/styles.js', /styles/) 58 | }) 59 | }) 60 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pixel2html/generator-frontend", 3 | "description": "Pixel2HTML Boilerplate Generator", 4 | "version": "2.4.3", 5 | "repository": "https://github.com/Pixel2HTML/pixel2html-generator", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Juan Manuel Garcia Olivares", 9 | "email": "jm@pixel2html.com" 10 | }, 11 | "contributors": [ 12 | { 13 | "name": "Miguel Palau", 14 | "email": "miguel@pixel2html.com", 15 | "url": "https://www.mpz.im/" 16 | }, 17 | { 18 | "name": "Diego Peralta", 19 | "url": "https://diego.earth/" 20 | }, 21 | { 22 | "name": "Bruno Belcastro", 23 | "url": "https://github.com/argen" 24 | }, 25 | { 26 | "name": "Matt Ginn", 27 | "url": "http://matt.codes/" 28 | }, 29 | { 30 | "name": "Juan Di Nella", 31 | "url": "https://github.com/juandinella" 32 | }, 33 | { 34 | "name": "Tomas Peralta", 35 | "url": "https://github.com/peraltatomas" 36 | } 37 | ], 38 | "keywords": [ 39 | "yeoman-generator" 40 | ], 41 | "scripts": { 42 | "lint": "eslint 'src/**/*.js' 'test/**/*.js'", 43 | "pretest": "npm run lint", 44 | "test": "mocha --timeout 5000 --require babel-register", 45 | "postversion": "git push; git push --tags", 46 | "commit": "git-cz" 47 | }, 48 | "main": "app/index.js", 49 | "dependencies": { 50 | "@pixel2html/eslint-config": "^1.2.0", 51 | "chalk": "^2.3.1", 52 | "eslint": "^4.18.0", 53 | "eslint-config-standard": "^11.0.0", 54 | "eslint-plugin-import": "^2.8.0", 55 | "eslint-plugin-node": "^6.0.0", 56 | "eslint-plugin-promise": "^3.6.0", 57 | "eslint-plugin-standard": "^3.0.1", 58 | "fs-extra": "^5.0.0", 59 | "gulp-eslint": "^4.0.2", 60 | "gulp-filter": "^5.1.0", 61 | "gulp-jsbeautifier": "^2.1.2", 62 | "mkdirp": "^0.5.1", 63 | "moment": "^2.20.1", 64 | "path": "^0.12.7", 65 | "update-notifier": "^2.3.0", 66 | "wiredep": "^4.0.0", 67 | "yeoman-generator": "^2.0.3" 68 | }, 69 | "devDependencies": { 70 | "babel-preset-env": "^1.6.1", 71 | "babel-register": "^6.26.0", 72 | "commitizen": "^2.9.6", 73 | "emoji-cz": "^0.3.0", 74 | "mocha": "^5.0.1", 75 | "yeoman-assert": "^3.1.0", 76 | "yeoman-test": "^1.7.0" 77 | }, 78 | "eslintConfig": { 79 | "extends": "@pixel2html/eslint-config", 80 | "env": { 81 | "browser": true, 82 | "node": true, 83 | "mocha": true 84 | } 85 | }, 86 | "config": { 87 | "commitizen": { 88 | "path": "./node_modules/emoji-cz" 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /test/bootstrap.js: -------------------------------------------------------------------------------- 1 | import helpers from 'yeoman-test' 2 | import assert from 'yeoman-assert' 3 | import path from 'path' 4 | 5 | describe('Bootstrap 4 features', function () { 6 | beforeEach(function () { 7 | return helpers.run(path.join(__dirname, '../app')) 8 | .withOptions({ 9 | 'skip-install': true 10 | }) 11 | .withPrompts({ 12 | projectName: 'Pixel2HTML', 13 | qtyScreens: 3, 14 | markupLanguage: 'html', 15 | frontEndFramework: 'bootstrap-4' 16 | }) 17 | .toPromise() 18 | }) 19 | 20 | it('Should list dependencies in package.json', function () { 21 | assert.fileContent('package.json', /"bootstrap"/) 22 | }) 23 | 24 | it('should exists a gulp routine', function () { 25 | assert.file([ 26 | 'gulp/common/styles.js', 27 | 'gulp/common/scripts.js' 28 | ]) 29 | }) 30 | 31 | it('should exists vendor files', function () { 32 | assert.file([ 33 | 'src/assets/styles/vendor/vendor.scss', 34 | 'src/assets/js/index.js' 35 | ]) 36 | }) 37 | 38 | it('should include bootstrap include', function () { 39 | assert.fileContent('src/assets/styles/vendor/vendor.scss', /import "bootstrap\/scss\/bootstrap.scss";/) 40 | assert.fileContent('src/assets/js/framework.js', /import 'bootstrap'/) 41 | }) 42 | }) 43 | 44 | describe('Bootstrap 3 features', function () { 45 | beforeEach(function () { 46 | return helpers.run(path.join(__dirname, '../app')) 47 | .withOptions({ 48 | 'skip-install': true 49 | }) 50 | .withPrompts({ 51 | projectName: 'Pixel2HTML', 52 | qtyScreens: 3, 53 | markupLanguage: 'html', 54 | frontEndFramework: 'bootstrap-3' 55 | }) 56 | .toPromise() 57 | }) 58 | 59 | it('Should list dependencies in package.json', function () { 60 | assert.fileContent('package.json', /"bootstrap-sass"/) 61 | }) 62 | 63 | it('should exists a gulp routine', function () { 64 | assert.file([ 65 | 'gulp/common/styles.js', 66 | 'gulp/common/scripts.js' 67 | ]) 68 | }) 69 | 70 | it('should exists vendor files', function () { 71 | assert.file([ 72 | 'src/assets/styles/vendor/vendor.scss', 73 | 'src/assets/js/index.js' 74 | ]) 75 | }) 76 | 77 | it('should include bootstrap include', function () { 78 | assert.fileContent('src/assets/styles/vendor/vendor.scss', /import "bootstrap-sass";/) 79 | assert.fileContent('src/assets/js/framework.js', /require\('bootstrap-sass'\)/) 80 | }) 81 | 82 | it('should include correct paths on config file', function () { 83 | assert.fileContent('gulp/config.js', './node_modules/bootstrap-sass/assets/fonts/**/*') 84 | }) 85 | }) 86 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 2.3.2 2 | - Removed jekyll 3 | - 100/100 lighthouse and google pagespeed insights 4 | - Bootstrap 4 out of beta 5 | - Fewer dependencies 6 | - Decouple gulp tasks from this package 7 | 8 | # 2.2.0 9 | - HMR 10 | - CSS HMR 11 | - PurifyCSS 12 | - CriticalCSS 13 | 14 | ### 2.1.0 15 | - Add Bootstrap 4 Beta as an Frontend Framework option 16 | - Decouple jQuery from bundle on production mode. 17 | - Keep alive the opened browser tab when you hit `npm run code`. Thanks Facebook! 18 | 19 | 20 | 21 | ### 2.0.0 22 | - Reduced number of total dependencies 23 | - Webpack integration to handle JS files 24 | - God mode svg inline icons with pug mixins 25 | - Unified fonts task 26 | - Deploy via FTP 27 | - Jekyll and HTML both are now Environment aware 💅 28 | - No more support to LESS & Stylus css preprocessors. (Help: https://github.com/Pixel2HTML/pixel2html-generator/wiki/Using-other-styles-preprocessor-language) 29 | - No more support to BassCss framework 30 | 31 | ### 1.3.5 32 | - Minor fixes. 33 | 34 | ### 1.3.4 35 | - Fixed some minor bugs on JS compilation. 36 | - Minor other fixes. 37 | 38 | ### 1.3.3 39 | - Fixed some minor bugs on Jekyll builds. 40 | - Smarter use of config variables to gulp routines. 41 | - Updated dependencies versions. 42 | - Some tests improvement. 43 | - `projectName` variable instead of `projectId` to generate more white label projects. 44 | 45 | ### 1.3.2 46 | - Fix some miss references to vendor fonts 47 | - Updated JS syntax to ES6 48 | - Minor fixes 49 | 50 | ### 1.3.1 51 | - Added missing references to vendor scripts on pug base files 52 | 53 | #### 1.3.0 54 | - Migrate to Gulp 4. 55 | - Import reset.css only when there no selected FrontEnd Framework. 56 | - Added `production` flag to gulp tasks to speed up the compilation process on `development` mode (no mins, no compressions). 57 | - Added CSScomb. 58 | - Added PurifyCSS. 59 | - Improvements in the PUG file structure, now it have some layouts, mixins and imports. 60 | - Moved `sourcemaps` to a external file. 61 | - Removed useless Gulp Plumber. 62 | - Added some SVG magic by default. 63 | 64 | #### 1.2.3 65 | - Added fonts support to default gulp routine. 66 | 67 | #### 1.2.2 68 | - Added `dist` directories configuration on `config.js` file. 69 | - Added Zurb Foundation initializer on `main.js` file. 70 | - Updated library versions. 71 | 72 | #### 1.2.1 73 | - Fixed version name. 74 | 75 | #### 1.2.0 76 | - Added Jekyll support. 77 | - Removed vendor gulp tasks in favor of `config.js`. 78 | - Added gulp group css media queries support. 79 | - Improved bower inclusion of libs on index.js. 80 | 81 | #### 1.1.2 82 | - Added PUG/Jade support. 83 | 84 | #### 1.1.0 85 | - Minor bugfixing. 86 | - Removed `gitlab-ci.yml` integration. 87 | - Add generator version to config file. 88 | 89 | #### 1.0.0 90 | - Initial release. -------------------------------------------------------------------------------- /app/templates/base/webpack.config.js: -------------------------------------------------------------------------------- 1 | const config = require('./gulp/config') 2 | const paths = require('./webpack/paths') 3 | 4 | const commonPlugins = require('./webpack/commonPlugins') 5 | const devPlugins = require('./webpack/developmentPlugins') 6 | const productionPlugins = require('./webpack/productionPlugins') 7 | 8 | const production = config.production 9 | const debug = config.debug 10 | 11 | let debugPlugins = [] 12 | 13 | if (debug) { 14 | debugPlugins = require('./webpack/debugPlugins') 15 | } 16 | 17 | let plugins = [ ...commonPlugins ] 18 | 19 | const shouldBeDebugMode = production || debug 20 | 21 | if (!shouldBeDebugMode) plugins = [...plugins, ...devPlugins] 22 | if (shouldBeDebugMode) plugins = [...plugins, ...productionPlugins] 23 | if (debug) plugins = [...plugins, ...debugPlugins] 24 | 25 | process.env.NODE_ENV = 'development' 26 | process.env.BABEL_ENV = 'development' 27 | 28 | if (shouldBeDebugMode) { 29 | process.env.NODE_ENV = 'production' 30 | process.env.BABEL_ENV = 'production' 31 | } 32 | 33 | module.exports = { 34 | entry: paths.entry, 35 | devtool: shouldBeDebugMode ? 'source-map' : 'inline-source-map', 36 | module: { 37 | rules: [ 38 | { 39 | test: /\.(js|jsx|mjs)$/, 40 | enforce: 'pre', 41 | use: [ 42 | { 43 | options: { 44 | eslintPath: require.resolve('eslint'), 45 | baseConfig: { 46 | extends: [require.resolve('@pixel2html/eslint-config')] 47 | }, 48 | ignore: false, 49 | useEslintrc: false 50 | }, 51 | loader: require.resolve('eslint-loader') 52 | } 53 | ], 54 | include: paths.src 55 | }, 56 | { 57 | test: /\.(js|jsx|mjs)$/, 58 | include: paths.src, 59 | use: { 60 | loader: 'babel-loader', 61 | options: { 62 | presets: [ 63 | require.resolve('@pixel2html/babel-preset') 64 | ], 65 | cacheDirectory: true 66 | } 67 | } 68 | } 69 | ]}, 70 | output: { 71 | filename: shouldBeDebugMode ? '[name].min.js' : '[name].js', 72 | chunkFilename: shouldBeDebugMode ? '[name].chunk.min.js' : '[name].chunk.js', 73 | path: paths.output, 74 | publicPath: '/' 75 | }, 76 | plugins, 77 | externals: shouldBeDebugMode ? { 78 | jquery: 'jQuery' 79 | } : {}, 80 | // Some libraries import Node modules but don't use them in the browser. 81 | // Tell Webpack to provide empty mocks for them so importing them works. 82 | node: { 83 | dgram: 'empty', 84 | fs: 'empty', 85 | net: 'empty', 86 | tls: 'empty', 87 | child_process: 'empty' 88 | }, 89 | resolve: { 90 | alias: { 91 | styles: paths.styles 92 | } 93 | }, 94 | bail: shouldBeDebugMode 95 | } 96 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@pixel2html.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /app/templates/styles/vendor/_reset.scss: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ 2 | // stylelint-disable 3 | html { 4 | font-family: sans-serif; 5 | -ms-text-size-adjust: 100%; 6 | -webkit-text-size-adjust: 100%; 7 | } 8 | 9 | body { 10 | margin: 0; 11 | } 12 | 13 | article, 14 | aside, 15 | details, 16 | figcaption, 17 | figure, 18 | footer, 19 | header, 20 | hgroup, 21 | main, 22 | menu, 23 | nav, 24 | section, 25 | summary { 26 | display: block; 27 | } 28 | 29 | audio, 30 | canvas, 31 | progress, 32 | video { 33 | display: inline-block; 34 | vertical-align: baseline; 35 | } 36 | 37 | audio:not([controls]) { 38 | display: none; 39 | height: 0; 40 | } 41 | 42 | [hidden], 43 | template { 44 | display: none; 45 | } 46 | 47 | a { 48 | background-color: transparent; 49 | } 50 | 51 | a:active, 52 | a:hover { 53 | outline: 0; 54 | } 55 | 56 | abbr[title] { 57 | border-bottom: 1px dotted; 58 | } 59 | 60 | b, 61 | strong { 62 | font-weight: bold; 63 | } 64 | 65 | dfn { 66 | font-style: italic; 67 | } 68 | 69 | h1 { 70 | font-size: 2em; 71 | margin: 0.67em 0; 72 | } 73 | 74 | mark { 75 | background: #ff0; 76 | color: #000; 77 | } 78 | 79 | small { 80 | font-size: 80%; 81 | } 82 | 83 | sub, 84 | sup { 85 | font-size: 75%; 86 | line-height: 0; 87 | position: relative; 88 | vertical-align: baseline; 89 | } 90 | 91 | sup { 92 | top: -0.5em; 93 | } 94 | 95 | sub { 96 | bottom: -0.25em; 97 | } 98 | 99 | img { 100 | border: 0; 101 | } 102 | 103 | svg:not(:root) { 104 | overflow: hidden; 105 | } 106 | 107 | figure { 108 | margin: 1em 40px; 109 | } 110 | 111 | hr { 112 | box-sizing: content-box; 113 | height: 0; 114 | } 115 | 116 | pre { 117 | overflow: auto; 118 | } 119 | 120 | code, 121 | kbd, 122 | pre, 123 | samp { 124 | font-family: monospace, monospace; 125 | font-size: 1em; 126 | } 127 | 128 | button, 129 | input, 130 | optgroup, 131 | select, 132 | textarea { 133 | color: inherit; 134 | font: inherit; 135 | margin: 0; 136 | } 137 | 138 | button { 139 | overflow: visible; 140 | } 141 | 142 | button, 143 | select { 144 | text-transform: none; 145 | } 146 | 147 | button, 148 | html input[type="button"], 149 | input[type="reset"], 150 | input[type="submit"] { 151 | -webkit-appearance: button; 152 | cursor: pointer; 153 | } 154 | 155 | button[disabled], 156 | html input[disabled] { 157 | cursor: default; 158 | } 159 | 160 | button::-moz-focus-inner, 161 | input::-moz-focus-inner { 162 | border: 0; 163 | padding: 0; 164 | } 165 | 166 | input { 167 | line-height: normal; 168 | } 169 | 170 | input[type="checkbox"], 171 | input[type="radio"] { 172 | box-sizing: border-box; 173 | padding: 0; 174 | } 175 | 176 | input[type="number"]::-webkit-inner-spin-button, 177 | input[type="number"]::-webkit-outer-spin-button { 178 | height: auto; 179 | } 180 | 181 | input[type="search"] { 182 | -webkit-appearance: textfield; 183 | box-sizing: content-box; 184 | } 185 | 186 | input[type="search"]::-webkit-search-cancel-button, 187 | input[type="search"]::-webkit-search-decoration { 188 | -webkit-appearance: none; 189 | } 190 | 191 | fieldset { 192 | border: 1px solid #c0c0c0; 193 | margin: 0 2px; 194 | padding: 0.35em 0.625em 0.75em; 195 | } 196 | 197 | legend { 198 | border: 0; 199 | padding: 0; 200 | } 201 | 202 | textarea { 203 | overflow: auto; 204 | } 205 | 206 | optgroup { 207 | font-weight: bold; 208 | } 209 | 210 | table { 211 | border-collapse: collapse; 212 | border-spacing: 0; 213 | } 214 | 215 | td, 216 | th { 217 | padding: 0; 218 | } 219 | -------------------------------------------------------------------------------- /test/markup.js: -------------------------------------------------------------------------------- 1 | import helpers from 'yeoman-test' 2 | import assert from 'yeoman-assert' 3 | import path from 'path' 4 | 5 | describe('Markup Features', function () { 6 | describe('HTML Project', function () { 7 | beforeEach(function () { 8 | return helpers.run(path.join(__dirname, '../app')) 9 | .withOptions({ 10 | 'skip-install': true 11 | }) 12 | .withPrompts({ 13 | projectName: 'Pixel2HTML', 14 | qtyScreens: 6, 15 | markupLanguage: 'html' 16 | }) 17 | .toPromise() 18 | }) 19 | 20 | it('creates expected base files', function () { 21 | assert.file([ 22 | '.gitignore', 23 | '.gitattributes', 24 | 'package.json', 25 | 'gulpfile.js', 26 | 'package.json', 27 | '.editorconfig', 28 | 'src/index.html', 29 | 'src/screen-2.html', 30 | 'src/screen-3.html', 31 | 'src/screen-4.html', 32 | 'src/screen-5.html', 33 | 'src/screen-6.html' 34 | ]) 35 | }) 36 | 37 | it('should have the project name on package.json', function () { 38 | assert.fileContent('package.json', /"name": "Pixel2HTML"/) 39 | }) 40 | 41 | it('should exists a gulp routine', function () { 42 | assert.file(['gulp/common/markup.js']) 43 | }) 44 | 45 | it('should have the gulp routine in gulp default\'s task', function () { 46 | assert.fileContent('gulpfile.js', /'markup'/) 47 | assert.fileContent('gulpfile.js', /'icons'/) 48 | assert.noFileContent('gulpfile.js', /'jekyll'/) 49 | }) 50 | 51 | it('should have the projectName in the title tag', function () { 52 | assert.fileContent('src/index.html', /Pixel2HTML - Screen 1<\/title>/) 53 | }) 54 | }) 55 | 56 | describe('PUG Project', function () { 57 | beforeEach('crafting project', function () { 58 | return helpers.run(path.join(__dirname, '../app')) 59 | .withOptions({ 60 | 'skip-install': true 61 | }) 62 | .withPrompts({ 63 | projectName: 'Pixel2HTML', 64 | qtyScreens: 6, 65 | markupLanguage: 'pug' 66 | }) 67 | .toPromise() 68 | }) 69 | 70 | it('creates expected base files', function () { 71 | assert.file([ 72 | '.gitignore', 73 | '.gitattributes', 74 | 'package.json', 75 | 'gulpfile.js', 76 | 'package.json', 77 | '.editorconfig', 78 | 'src/pug/index.pug', 79 | 'src/pug/screen-2.pug', 80 | 'src/pug/screen-3.pug', 81 | 'src/pug/screen-4.pug', 82 | 'src/pug/screen-5.pug', 83 | 'src/pug/screen-6.pug', 84 | 'src/pug/layouts/layout-primary.pug', 85 | 'src/pug/layouts/general/footer.pug', 86 | 'src/pug/layouts/general/menu.pug', 87 | 'src/pug/layouts/includes/mixins.pug', 88 | 'gulp', 89 | 'src/assets/fonts', 90 | 'src/assets/icons', 91 | 'src/assets/images', 92 | 'src/assets/js', 93 | 'src/assets/styles' 94 | ]) 95 | }) 96 | 97 | it('should have the project name on package.json', function () { 98 | assert.fileContent('package.json', /"name": "Pixel2HTML"/) 99 | }) 100 | 101 | it('should exists a gulp routine', function () { 102 | assert.file([ 103 | 'gulp/common/markup.js' 104 | ]) 105 | assert.fileContent('gulp/common/markup.js', /pug/) 106 | }) 107 | 108 | it('should exists a pipe in the main:markup', function () { 109 | assert.fileContent('gulp/common/markup.js', /pug\(/) 110 | }) 111 | 112 | it('should have the gulp routine in gulp default\'s task', function () { 113 | assert.fileContent('gulpfile.js', /'markup'/) 114 | assert.noFileContent('gulpfile.js', /'jekyll'/) 115 | assert.noFileContent('gulpfile.js', /'icons'/) 116 | }) 117 | }) 118 | }) 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @pixel2html/generator-frontend 2 | 3 | [![Build Status](https://travis-ci.org/Pixel2HTML/pixel2html-generator.svg?branch=master)](https://travis-ci.org/Pixel2HTML/pixel2html-generator) 4 | 5 | <img src="https://cldup.com/2znve50RiO.svg" alt="Cool demo" /> 6 | 7 | We aim to generate a boilerplate code for projects when we know the specs. 💕 8 | 9 | ## How to install 10 | 11 | #### Node 12 | 13 | You will need `node` installed in your machine. In case you don't have it (you can check this typing `node --version` in your terminal) please visit [this link](https://nodejs.org/en/download/). 14 | 15 | We also need to install **Yeoman**, and the **Pixel2HTML Generator**, so run this command in your terminal. The `-g` parameter is to install them globally so can use it in every project. 16 | ```shell 17 | $ npm install -g yo @pixel2html/generator-frontend 18 | ``` 19 | 20 | ## Running the generator 21 | 22 | To generate the **Pixel2HTML Boilerplate** go to your project folder and run this command in your shell 23 | 24 | ``` 25 | $ cd ~/your/project/folder 26 | $ yo @pixel2html/frontend 27 | ``` 28 | The **Pixel2HTML Boilerplate** will ask you questions about this points. Answering with the desired options will generate the code. 29 | 30 | * Project Name? 31 | * Quantity of screens? 32 | * Markup Language? _Options: HTML / Pug_ 33 | * Frontend Framework _Options: None / Bootstrap 3.*/ Bootstrap 4 Beta / Foundation_ 34 | * jQuery? _Options: true / false_ 35 | 36 | There are also two more way to generate your files, you can find the instructions in the [Wiki](https://github.com/Pixel2HTML/pixel2html-generator/wiki/Running-the-Pixel2HTML-Generator) 37 | 38 | 39 | ## Installing dependencies & running up 40 | To work, the **Pixel2HTML Boilerplate** needs to install some dependencies to run the options you select. 41 | For this job, run this command in your shell 42 | 43 | ``` 44 | $ npm run start 45 | ``` 46 | 47 | ## Generated file structure 48 | 49 | This boilerplate will create a set of files and folders 50 | 51 | ``` 52 | 53 | ├── dist/ 54 | ├── gulp/ 55 | ├── src/ 56 | │ └── assets/ 57 | │ │ ├── fonts/ 58 | │ │ ├── icons/ 59 | │ │ ├── images/ 60 | │ │ ├── js/ 61 | │ │ ├── styles/ 62 | │ │ │ ├── components/ 63 | │ │ │ │ ├── _buttons.scss 64 | │ │ │ │ ├── _forms.scss 65 | │ │ │ │ └── _nav.scss 66 | │ │ │ ├── screens/ 67 | │ │ │ │ ├── _base.scss 68 | │ │ │ │ └── screen_*.scss 69 | │ │ │ ├── _mixins.scss 70 | │ │ │ ├── _reset.scss 71 | │ │ │ ├── _variables.scss 72 | │ │ │ ├── main.scss 73 | │ │ │ └── vendor.scss 74 | │ └── screen_*.[html|pug] 75 | ├── .editorcofig 76 | ├── .gitattributes 77 | ├── .gitignore 78 | ├── .project.conf 79 | ├── gulpfile.js 80 | ├── package.json 81 | └── README.md 82 | ``` 83 | 84 | ## How to work with script files 85 | 86 | We are using [WebpackJS](https://webpack.js.org/) to bundle our script files. There's also ES6 on-demand transpilation and polyfills. 87 | 88 | Learn more about Javascript Modules here [Wes Bos Article About Modules](http://wesbos.com/javascript-modules/) 89 | 90 | ### Example 91 | 92 | ```js 93 | import $ from 'jquery' 94 | import 'bootstrap-sass' 95 | 96 | ``` 97 | 98 | We also included the amazing `webpack-bundle-analyzer` you can fine tweak you JS bundle size if you wish to. Fire it up running this command: 99 | 100 | ``` 101 | $ npm run debug 102 | ``` 103 | 104 | 105 | 106 | ## Available script commands. 107 | 108 | ### Start to code. 109 | * `$ npm run code` 110 | 111 | ### Build the project 112 | * `$ npm run build` 113 | 114 | 115 | ## Available Gulp Commands 116 | 117 | ### Helpers 118 | * `$ gulp clean` Clean /dist directory 119 | 120 | ### Static Files 121 | * `$ gulp main:static` Compile static files (images, icons) 122 | * `$ gulp main:images` Move images 123 | * `$ gulp main:icons` Move icons 124 | 125 | ### Fonts Files 126 | * `$ gulp main:fonts` Move project fonts 127 | * `$ gulp vendor:fonts` Move vendors fonts 128 | 129 | ### Scripts 130 | * `$ gulp main:scripts` Concat, uglify and move project JS files 131 | * `$ gulp vendor:scripts` Concat, uglify and move vendors JS files 132 | 133 | ### Styles 134 | * `$ gulp main:styles` Compile, concat, autoprefix and move [SCSS, Less, Stylus] project files 135 | * `$ gulp vendor:styles` Compile, concat, autoprefix and move [SCSS, Less, Stylus] vendor files 136 | 137 | ### Delivery 138 | * `$ gulp build` Execute all the gulp directives and makes a `.zip` file with the latest code. 139 | * `$ gulp release` Execute all the gulp directives and makes a `.zip` file with the latest code. 140 | * `$ gulp release --prod` Execute all the gulp directives, prepare assets to production and makes a `.zip` file with the latest code. 141 | -------------------------------------------------------------------------------- /app/templates/base/README.md.ejs: -------------------------------------------------------------------------------- 1 | # <%= projectName %> 2 | 3 | ## Installing dependencies & running up 4 | To work, the **Pixel2HTML Boilerplate** needs to install some dependencies to run the options you select. 5 | For this job, run this command in your shell 6 | 7 | ``` 8 | $ npm run start 9 | $ npm run code 10 | ``` 11 | 12 | ### Other available npm commands 13 | 14 | ``` 15 | $ npm run build // build the project without serving 16 | 17 | $ npm run code --tunnel // create a tunnel to share your project everywhere 18 | ``` 19 | 20 | ## File Structure 21 | 22 | This boilerplate will create a set of files and folders 23 | 24 | ``` 25 | 26 | ├── dist/ 27 | ├── src/ 28 | │ ├── assets/ 29 | │ │ ├── gulp/ 30 | │ │ │ ├── tasks/ 31 | │ │ │ ├── config.js 32 | │ │ │ └── helpers.js 33 | │ │ ├── fonts/ 34 | │ │ ├── icons/ 35 | │ │ ├── images/ 36 | │ │ ├── js/ 37 | │ │ ├── styles/ 38 | │ │ │ ├── components/ 39 | │ │ │ │ ├── _buttons.scss 40 | │ │ │ │ ├── _footer.scss 41 | │ │ │ │ ├── _forms.scss 42 | │ │ │ │ ├── _header.scss 43 | │ │ │ │ └── _nav.scss 44 | │ │ │ ├── screens/ 45 | │ │ │ │ ├── _base.scss 46 | <% for(var i=1; i<=qtyScreens; i++) {%>│ │ │ │ └── screen_<%=i%>.scss 47 | <% } %>│ │ │ ├── _variables.scss 48 | │ │ │ ├── _reset.scss 49 | │ │ │ ├── _mixins.scss 50 | <% if (frontEndFramework) { -%>│ │ │ ├── vendors.scss<% } %> 51 | │ │ │ └── main.scss 52 | │ │ └── vendor/ 53 | <% for(var i=1; i<=qtyScreens; i++) {%>│ └── screen_<%=i%>.<%=markupLanguage%> 54 | <% } %>├── .editorcofig 55 | ├── .gitattributes 56 | ├── .gitignore 57 | ├── .browserlistrc 58 | ├── .babelrc 59 | ├── .project.conf 60 | ├── gulpfile.js 61 | ├── LICENSE 62 | ├── package.json 63 | └── README.md 64 | ``` 65 | 66 | ## Gulp Config file 67 | 68 | You have a config file located at `gulp/config.js` that enables you to add thrid-party libraries easily. 69 | 70 | ### SCSS Directories 71 | 72 | We are using [`sass-module-importer`](https://www.npmjs.com/package/sass-module-importer) so we can import sass libraries just using the npm package name like: 73 | 74 | #### Example 75 | ```scss 76 | import "bootstrap-sass"; 77 | ``` 78 | 79 | That is the external library fits under one of these categories: 80 | 81 | * Set a SCSS/Sass/CSS file on the "main" field of their package.json/bower.json 82 | * Set a SCSS/Sass/CSS file on the "style" field of their package.json/bower.json 83 | * Have a index.css file on the root of their module 84 | 85 | However fear not, if your module doesn't fit into those categories you can also *navigate* to your desired scss or css file like this: 86 | 87 | ```scss 88 | @import "module-name/folder/to/_file.scss"; 89 | ``` 90 | 91 | ### Script Files 92 | 93 | We are using [WebpackJS](https://webpack.js.org/) to bundle our script files. There's also ES6 on-demand transpilation and pollyfills. 94 | 95 | Learn more about Javascript Modules here [Wesbos Article About Modules](http://wesbos.com/javascript-modules/) 96 | 97 | Also learn more about ES6 here: [Babel Overview of ES2015](https://babeljs.io/learn-es2015/) 98 | 99 | #### Example 100 | ```js 101 | import $ from 'jquery' 102 | import 'bootstrap-sass' 103 | ``` 104 | 105 | We also included the amazing [`webpack-bundle-analyzer`](https://github.com/webpack-contrib/webpack-bundle-analyzer) you can fine tweak you JS bundle size if you wish to. Fire it up running this command: 106 | 107 | ```sh 108 | $ npm run debug 109 | ``` 110 | 111 | ### Font Files 112 | 113 | You can add file paths to `fontFiles` key, who will move this fonts to the correct folder `./dist/assets/fonts`. 114 | You can point to specific files or complete directories using wildcards (`**/*`) 115 | 116 | #### Example 117 | ``` 118 | fontFiles: [ 119 | './path/to/bootstrap/fonts/**/*', 120 | './node_modules/library/font/font.ttf' 121 | ] 122 | ``` 123 | 124 | ## Available Gulp Commands 125 | 126 | ### Helpers 127 | * `$ gulp clean` Clean /dist directory 128 | 129 | ### Images 130 | * `$ gulp images` Move images 131 | 132 | ### Fonts Files 133 | * `$ gulp fonts` Move project fonts 134 | 135 | ### Scripts 136 | * `$ gulp scripts` Process script files with webpack 137 | 138 | ### Styles 139 | * `$ gulp styles` Compile, concat, autoprefix, minify and move [SCSS, Less, Stylus] project files 140 | 141 | ### Daemons 142 | * `$ gulp watch` **Watch** your files and autoexecute gulp directives 143 | * `$ gulp serve` **Watch** your files and **serve** with an HTTP server and **Sync** with your prefered browser _awesome!_ 144 | 145 | ### Delivery 146 | * `$ gulp build` Execute all the gulp directives and makes a `.zip` file with the latest code. 147 | 148 | ### FTP Upload 149 | * `$ gulp ftp` will upload your dist folder via FTP you must specify the credentials on the `config.deploy.ftp` object. It's powered by: [Vinyl-FTP](https://www.npmjs.com/package/vinyl-ftp) 150 | 151 | ### EditorConfig Please note we use 152 | [EditorConfig](http://editorconfig.org/) to help us try to standarize 153 | stuff like tabs spaces and such. Please visit the link provided to 154 | download a plugin for your text editor of choice like Vim, Coda, Atom, 155 | Sublime Text, Visual Studio, Emacs Notepad++ and more. 156 | 157 | --- 158 | 159 | ##### Generated with 💕 by Pixel2HTML v<%= version %> @ <%= now %> 160 | -------------------------------------------------------------------------------- /app/templates/assets/icons/react.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8" standalone="no" ?> 2 | <svg width="256px" height="230px" viewBox="0 0 256 230" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid"> 3 | <path d="M0.754124112,114.750341 C0.754124112,133.964682 19.5166032,151.90205 49.0972,162.012525 C43.1902309,191.75023 48.0385672,215.718618 64.2325395,225.058104 C80.878267,234.657205 105.676296,228.01262 129.212992,207.438816 C152.155865,227.182074 175.343729,234.952033 191.522612,225.586005 C208.152063,215.959037 213.210383,190.365003 207.140052,159.699094 C237.94981,149.512664 255.183937,134.217604 255.183937,114.750341 C255.183937,95.9814665 236.386646,79.743862 207.205024,69.6979922 C213.73997,37.7647117 208.20272,14.3779364 191.338416,4.65275505 C175.079459,-4.72292197 151.622419,3.44893641 128.342126,23.7092591 C104.122937,2.20452764 80.8973474,-4.36113675 64.049392,5.39238954 C47.8062377,14.7947358 43.1711096,39.1986962 49.0971999,69.4869405 C20.5154295,79.4522024 0.754124112,96.0565259 0.754124112,114.750341 Z" fill="#FFFFFF"></path> 4 | <path d="M201.024553,79.6741178 C198.680534,78.8673056 196.251651,78.1039308 193.750774,77.3819828 C194.161823,75.7044085 194.539085,74.048553 194.87452,72.4208515 C200.380632,45.6934862 196.780544,24.1617345 184.487315,17.0725656 C172.699651,10.2749914 153.421826,17.3625515 133.952151,34.3064132 C132.079912,35.9357235 130.202444,37.6607573 128.325782,39.4686441 C127.075343,38.2725027 125.826916,37.1165813 124.581707,36.0109348 C104.176918,17.8934548 83.7242671,10.2585012 71.4431045,17.3681823 C59.6667022,24.1854643 56.1792302,44.4273621 61.135535,69.7570841 C61.6141524,72.2036638 62.1736119,74.7021273 62.8062718,77.2424195 C59.9116418,78.0641131 57.1171595,78.9401037 54.443337,79.872 C30.5209112,88.2124116 15.2429599,101.283896 15.2429599,114.842444 C15.2429599,128.845826 31.6438523,142.891438 56.5609175,151.408012 C58.527271,152.080088 60.5676292,152.715563 62.6703284,153.318862 C61.9877958,156.066288 61.3941493,158.758611 60.895824,161.384572 C56.1699796,186.27469 59.8605624,206.038372 71.6055931,212.812619 C83.7371375,219.808478 104.097282,212.617552 123.922903,195.287579 C125.489873,193.917687 127.062473,192.464943 128.637888,190.942216 C130.679856,192.908569 132.718604,194.769546 134.746495,196.515092 C153.949914,213.040264 172.916437,219.713157 184.650608,212.920007 C196.770086,205.904037 200.708827,184.673131 195.595261,158.842269 C195.204725,156.86948 194.75024,154.854058 194.239849,152.802841 C195.669668,152.380128 197.073345,151.943742 198.44203,151.490061 C224.345691,142.907526 241.199459,129.032848 241.199459,114.842444 C241.199459,101.234828 225.428813,88.0752616 201.024553,79.6741178 L201.024553,79.6741178 L201.024553,79.6741178 Z" fill="#53C1DE"></path> 5 | <path d="M195.406228,142.327554 C194.170671,142.73659 192.902938,143.131953 191.611073,143.515249 C188.751435,134.46214 184.891928,124.835494 180.168899,114.889502 C184.675947,105.180405 188.386237,95.6768327 191.165838,86.6824446 C193.477279,87.3513024 195.720748,88.0567605 197.882571,88.8012318 C218.792119,95.9993967 231.546671,106.641998 231.546671,114.842444 C231.546671,123.577414 217.772142,134.916625 195.406228,142.327554 L195.406228,142.327554 L195.406228,142.327554 Z M186.125876,160.71692 C188.387041,172.138985 188.710007,182.46586 187.212216,190.538809 C185.866457,197.79288 183.160056,202.629329 179.813756,204.566322 C172.692813,208.688063 157.464736,203.330363 141.041722,189.197876 C139.159026,187.577816 137.262655,185.847956 135.360251,184.017143 C141.72707,177.053863 148.090269,168.958794 154.300632,159.968427 C165.223968,158.999127 175.544007,157.41446 184.902787,155.251029 C185.363708,157.110397 185.773147,158.93397 186.125876,160.71692 L186.125876,160.71692 L186.125876,160.71692 Z M92.2766379,203.854027 C85.3193904,206.311064 79.7782875,206.381449 76.4287698,204.450086 C69.301392,200.339205 66.3383881,184.470825 70.3800911,163.184817 C70.8430228,160.747085 71.3940362,158.242992 72.0291092,155.683394 C81.2853291,157.730187 91.5297533,159.203041 102.479233,160.090696 C108.731425,168.888007 115.278429,176.974228 121.87611,184.054548 C120.434627,185.446158 118.998774,186.771004 117.570966,188.019431 C108.804223,195.682539 100.018979,201.119472 92.2766379,203.854027 L92.2766379,203.854027 L92.2766379,203.854027 Z M59.6827903,142.274061 C48.6649364,138.508267 39.5659765,133.613901 33.3290683,128.273094 C27.7248202,123.473647 24.8953464,118.708789 24.8953464,114.842444 C24.8953464,106.614649 37.1620299,96.1200565 57.6207133,88.9870479 C60.1030888,88.1215145 62.7016999,87.3058539 65.3984478,86.5396638 C68.2259104,95.7371626 71.9349945,105.353351 76.4110731,115.077329 C71.8770778,124.945696 68.1153056,134.715124 65.2600911,144.020411 C63.3375774,143.467789 61.4749914,142.886209 59.6827903,142.274061 L59.6827903,142.274061 L59.6827903,142.274061 Z M70.6085405,67.9033464 C66.3621178,46.2014643 69.182341,29.8303347 76.2791516,25.7222687 C83.8384918,21.3459356 100.554306,27.585659 118.172255,43.2292097 C119.298413,44.2290778 120.428996,45.2756009 121.562797,46.3583221 C114.997694,53.4076732 108.510618,61.4331626 102.31393,70.1785891 C91.6870133,71.1635758 81.5145828,72.7458288 72.1618351,74.8646158 C71.5738193,72.4992804 71.0529709,70.1753716 70.6085405,67.9033464 L70.6085405,67.9033464 L70.6085405,67.9033464 Z M168.075965,91.970564 C165.840139,88.1086441 163.544785,84.3380235 161.204789,80.6703661 C168.414216,81.5817502 175.321589,82.7915664 181.808264,84.2720629 C179.860813,90.5133951 177.43354,97.0390825 174.576314,103.728867 C172.526706,99.8375868 170.35885,95.9141304 168.075965,91.970564 L168.075965,91.970564 L168.075965,91.970564 Z M128.328999,53.2568484 C132.781348,58.0804274 137.240132,63.465879 141.625716,69.3090337 C137.206347,69.1002922 132.732279,68.9916983 128.22121,68.9916983 C123.752773,68.9916983 119.311686,69.097879 114.919667,69.3030007 C119.309675,63.5141429 123.80707,58.1359308 128.328999,53.2568484 L128.328999,53.2568484 L128.328999,53.2568484 Z M88.3274407,92.0373291 C86.0940267,95.9101084 83.9663912,99.8122483 81.9489584,103.721628 C79.1379858,97.0551705 76.7332349,90.4997203 74.7688924,84.1699041 C81.2157486,82.7272144 88.0905452,81.5475633 95.254121,80.6534737 C92.8811438,84.3549159 90.5668876,88.1532883 88.3274407,92.0365247 L88.3274407,92.0373291 L88.3274407,92.0373291 Z M95.4604493,149.719981 C88.0591736,148.894265 81.0810118,147.775347 74.6357643,146.372474 C76.6314784,139.92964 79.0893197,133.234225 81.9598177,126.424182 C83.9824792,130.330746 86.1185609,134.234495 88.3656497,138.115721 L88.3660518,138.115721 C90.6549694,142.069744 93.0263378,145.942925 95.4604493,149.719981 L95.4604493,149.719981 L95.4604493,149.719981 Z M128.59606,177.108562 C124.02104,172.172367 119.457684,166.712107 115.000911,160.838787 C119.327371,161.008515 123.738293,161.095391 128.22121,161.095391 C132.826797,161.095391 137.379695,160.991623 141.861003,160.792132 C137.460939,166.771231 133.018244,172.239937 128.59606,177.108562 L128.59606,177.108562 L128.59606,177.108562 Z M174.668418,126.077084 C177.688534,132.960729 180.234457,139.621153 182.255912,145.954187 C175.704484,147.44876 168.631001,148.652544 161.178244,149.547036 C163.523872,145.829907 165.839334,141.994532 168.114576,138.049357 C170.416365,134.05793 172.601917,130.060469 174.668418,126.077084 L174.668418,126.077084 L174.668418,126.077084 Z M159.75325,133.226985 C156.221134,139.351277 152.594903,145.197649 148.913571,150.71623 C142.208502,151.195651 135.28142,151.442602 128.22121,151.442602 C121.189556,151.442602 114.34975,151.224207 107.763331,150.796669 C103.933587,145.205694 100.228525,139.342027 96.7189317,133.279673 L96.7197361,133.279673 C93.2193935,127.23381 89.9977754,121.136867 87.0786112,115.074112 C89.9969709,108.997279 93.2101429,102.893499 96.6903755,96.8584949 L96.6895711,96.8597015 C100.179054,90.8086096 103.851538,84.9734988 107.645888,79.4175145 C114.365838,78.9095366 121.256723,78.6444871 128.220808,78.6444871 L128.22121,78.6444871 C135.216666,78.6444871 142.116399,78.9115475 148.834337,79.4239498 C152.570771,84.9393119 156.218319,90.7555192 159.721477,96.8074156 C163.264453,102.927284 166.519051,108.990441 169.462347,114.936962 C166.5279,120.98564 163.280541,127.109933 159.75325,133.226985 L159.75325,133.226985 L159.75325,133.226985 Z M179.665747,25.4350982 C187.232327,29.7985609 190.174818,47.3963991 185.42082,70.472597 C185.117561,71.9450495 184.776095,73.4448515 184.405266,74.9647635 C175.030799,72.8017345 164.851129,71.192132 154.193245,70.1922639 C147.98449,61.3507117 141.550504,53.3127541 135.092386,46.3538978 C136.828682,44.6835633 138.562564,43.0908531 140.289206,41.5878335 C156.970834,27.0704415 172.562099,21.338696 179.665747,25.4350982 L179.665747,25.4350982 L179.665747,25.4350982 Z" fill="#FFFFFF"></path> 6 | <path d="M128.22121,94.6653008 C139.36455,94.6653008 148.398353,103.698702 148.398353,114.842444 C148.398353,125.985784 139.36455,135.019589 128.22121,135.019589 C117.07787,135.019589 108.044066,125.985784 108.044066,114.842444 C108.044066,103.698702 117.07787,94.6653008 128.22121,94.6653008" fill="#53C1DE"></path> 7 | </svg> 8 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | const Generator = require('yeoman-generator') 2 | const chalk = require('chalk') 3 | const mkdirp = require('mkdirp') 4 | const fs = require('fs-extra') 5 | const moment = require('moment') 6 | const updateNotifier = require('update-notifier') 7 | const pkg = require('../package.json') 8 | 9 | const filter = require('gulp-filter') 10 | const prettify = require('gulp-jsbeautifier') 11 | const eslint = require('gulp-eslint') 12 | 13 | const filesToAssert = require('./filesToAssert') 14 | 15 | class PixelGenerator extends Generator { 16 | constructor (args, options) { 17 | super(args, options) 18 | this.paths = { 19 | src: { 20 | gulp: 'gulp', 21 | gulp_tasks: 'gulp/tasks', 22 | fonts: 'src/assets/fonts', 23 | icons: 'src/assets/icons', 24 | images: 'src/assets/images', 25 | scripts: 'src/assets/js', 26 | styles: 'src/assets/styles', 27 | head: 'src/assets/head', 28 | markup: 'src', 29 | base: 'src' 30 | }, 31 | dist: { 32 | assets: 'dist/assets', 33 | fonts: 'dist/assets/fonts', 34 | icons: 'dist/assets/icons', 35 | images: 'dist/assets/images', 36 | scripts: 'dist/assets/js', 37 | styles: 'dist/assets/css', 38 | base: 'dist', 39 | markup: 'dist' 40 | }, 41 | releases: { 42 | base: 'dist/releases' 43 | } 44 | } 45 | 46 | this.option('projectName', { 47 | desc: 'Sets the Project Name', 48 | type: String, 49 | required: false 50 | }) 51 | 52 | this.option('qtyScreens', { 53 | desc: 'Sets the quantity of screens have the project i.e. 5 (1 homepage, 4 inners)', 54 | type: Number, 55 | required: false 56 | }) 57 | 58 | this.option('markupLanguage', { 59 | desc: 'Sets the Markup Language [html, pug]', 60 | type: String, 61 | required: false 62 | }) 63 | 64 | this.option('frontEndFramework', { 65 | desc: 'Sets the framework of choice [bootstrap, foundation]', 66 | type: String, 67 | required: false 68 | }) 69 | 70 | this.option('jQuery', { 71 | desc: 'Sets the usage of jQuery', 72 | type: String, 73 | required: false 74 | }) 75 | 76 | this.option('yarn', { 77 | desc: 'Sets the usage of yarn', 78 | type: String, 79 | required: false 80 | }) 81 | } 82 | 83 | notify () { 84 | updateNotifier({pkg}).notify() 85 | } 86 | 87 | readConfigFile () { 88 | return fs.readJson('./.project.conf') 89 | .then(config => { 90 | this.options.projectName = config.projectName 91 | this.options.qtyScreens = config.qtyScreens 92 | this.options.markupLanguage = config.markupLanguage 93 | this.options.frontEndFramework = config.frontEndFramework 94 | this.options.jQuery = config.jQuery 95 | this.options.yarn = config.yarn 96 | }) 97 | .catch(err => { 98 | let okayError = err.toString() !== "Error: ENOENT: no such file or directory, open './.project.conf'" 99 | if (okayError) { 100 | this.log(chalk.cyan('There was an issue:') + '\n') 101 | this.log(chalk.white(err) + '\n') 102 | } 103 | }) 104 | } 105 | 106 | welcome () { 107 | if (!this.options['skip-welcome-message']) { 108 | this.log('') 109 | this.log(chalk.cyan(' ****************************************************') + '\n') 110 | this.log(chalk.cyan(' Welcome to'), chalk.white.bold(' Pixel2HTML Generator ')) 111 | this.log(chalk.white(' A Yeoman generator for scaffolding web projects') + '\n') 112 | this.log(chalk.cyan(' ****************************************************') + '\n') 113 | } 114 | } 115 | 116 | askForProjectName () { 117 | return this.options.projectName 118 | ? true 119 | : this.prompt( 120 | [{ 121 | type: 'input', 122 | name: 'projectName', 123 | required: true, 124 | message: 'Give me the Project Name!' 125 | }] 126 | ) 127 | .then(props => { 128 | this.options.projectName = props.projectName 129 | }) 130 | } 131 | 132 | askForQtyScreens () { 133 | return this.options.qtyScreens 134 | ? true 135 | : this.prompt( 136 | [{ 137 | type: 'input', 138 | name: 'qtyScreens', 139 | message: 'How many screens do you need to code?', 140 | default: 1 141 | }] 142 | ) 143 | .then(props => { 144 | this.options.qtyScreens = parseInt(props.qtyScreens) 145 | }) 146 | } 147 | 148 | askForMarkupLanguage () { 149 | return this.options.markupLanguage 150 | ? true 151 | : this.prompt([ 152 | { 153 | type: 'list', 154 | name: 'markupLanguage', 155 | message: 'What markup lenguage/integration would you like to use? Pick one', 156 | choices: [ 157 | { 158 | name: 'HTML', 159 | value: 'html' 160 | }, 161 | { 162 | name: 'pug/jade', 163 | value: 'pug' 164 | } 165 | ] 166 | }] 167 | ) 168 | .then(props => { 169 | this.options.markupLanguage = props.markupLanguage 170 | }) 171 | } 172 | 173 | askForFrontEndFramework () { 174 | return this.options.frontEndFramework 175 | ? true 176 | : this.prompt([{ 177 | type: 'list', 178 | name: 'frontEndFramework', 179 | message: 'What FrontEnd Framework do you like to include?', 180 | choices: [ 181 | { 182 | name: 'None', 183 | value: false 184 | }, { 185 | name: 'Bootstrap 3', 186 | value: 'bootstrap-3' 187 | }, { 188 | name: 'Bootstrap 4', 189 | value: 'bootstrap-4' 190 | }, { 191 | name: 'Foundation', 192 | value: 'foundation' 193 | }] 194 | }]) 195 | .then(props => { 196 | this.options.frontEndFramework = props.frontEndFramework 197 | }) 198 | } 199 | 200 | askForjQuery () { 201 | return this.options.jQuery || this.options.frontEndFramework 202 | ? true 203 | : this.prompt([{ 204 | type: 'confirm', 205 | name: 'jQuery', 206 | message: 'Would you like to use jQuery? \n http://youmightnotneedjquery.com/ \n http://youmightnotneedjqueryplugins.com/ \n', 207 | default: false 208 | }]) 209 | .then(props => { 210 | this.options.jQuery = props.jQuery 211 | }) 212 | } 213 | 214 | askForYarnInstall () { 215 | return this.options.yarn 216 | ? true 217 | : this.prompt([{ 218 | type: 'confirm', 219 | name: 'yarn', 220 | message: 'Should I install extra dependencies needed with Yarn?', 221 | default: true 222 | }]) 223 | .then(props => { 224 | this.options.yarn = props.yarn 225 | }) 226 | } 227 | 228 | writeProjectFiles () { 229 | this.log(chalk.yellow('Copying package.json file and adding dependencies.')) 230 | this.fs.copyTpl( 231 | this.templatePath('base/package.json.ejs'), 232 | this.destinationPath('package.json'), { 233 | projectName: this.options.projectName, 234 | markupLanguage: this.options.markupLanguage, 235 | frontEndFramework: this.options.frontEndFramework, 236 | jQuery: this.options.jQuery 237 | } 238 | ) 239 | 240 | this.log(chalk.yellow('Copying webpack config file.')) 241 | this.fs.copyTpl( 242 | this.templatePath('base/webpack.config.js'), 243 | this.destinationPath('webpack.config.js'), { 244 | frontEndFramework: this.options.frontEndFramework, 245 | jQuery: this.options.jQuery 246 | } 247 | ) 248 | 249 | this.log(chalk.yellow('Copying tern project file.')) 250 | this.fs.copyTpl( 251 | this.templatePath('base/tern-project.json.ejs'), 252 | this.destinationPath('.tern-project'), { 253 | frontEndFramework: this.options.frontEndFramework, 254 | jQuery: this.options.jQuery 255 | } 256 | ) 257 | 258 | this.log(chalk.yellow('Copying editorconfig file.')) 259 | this.fs.copy( 260 | this.templatePath('base/editorconfig'), 261 | this.destinationPath('.editorconfig') 262 | ) 263 | 264 | this.log(chalk.yellow('Copying MIT License')) 265 | this.fs.copy( 266 | this.templatePath('base/LICENSE'), 267 | this.destinationPath('LICENSE') 268 | ) 269 | 270 | this.log(chalk.yellow('Copying git files.')) 271 | this.fs.copyTpl( 272 | this.templatePath('git/gitignore'), 273 | this.destinationPath('.gitignore'), { 274 | paths: this.paths 275 | } 276 | ) 277 | 278 | this.fs.copy( 279 | this.templatePath('git/gitattributes'), 280 | this.destinationPath('.gitattributes') 281 | ) 282 | 283 | this.log(chalk.yellow('Copying README file.')) 284 | this.fs.copyTpl( 285 | this.templatePath('base/README.md.ejs'), 286 | this.destinationPath('README.md'), { 287 | paths: this.paths, 288 | projectName: this.options.projectName, 289 | frontEndFramework: this.options.frontEndFramework, 290 | jQuery: this.options.jQuery, 291 | qtyScreens: this.options.qtyScreens, 292 | markupLanguage: this.options.markupLanguage, 293 | now: moment().format(), 294 | version: pkg.version 295 | } 296 | ) 297 | } 298 | 299 | createFolders () { 300 | this.log(chalk.yellow('Creating directories.')) 301 | 302 | const srcPaths = Object.keys(this.paths.src) 303 | srcPaths.forEach(path => mkdirp(this.paths.src[path])) 304 | const releasesPaths = Object.keys(this.paths.releases) 305 | releasesPaths.forEach(path => mkdirp(this.paths.releases[path])) 306 | } 307 | 308 | copyGitKeepFiles () { 309 | this.fs.copy( 310 | this.templatePath('base/gitkeep'), 311 | this.destinationPath(this.paths.releases.base + '/.gitkeep') 312 | ) 313 | this.fs.copy( 314 | this.templatePath('base/gitkeep'), 315 | this.destinationPath(this.paths.src.fonts + '/.gitkeep') 316 | ) 317 | this.fs.copy( 318 | this.templatePath('base/gitkeep'), 319 | this.destinationPath(this.paths.src.icons + '/.gitkeep') 320 | ) 321 | this.fs.copy( 322 | this.templatePath('base/gitkeep'), 323 | this.destinationPath(this.paths.src.images + '/.gitkeep') 324 | ) 325 | } 326 | 327 | copySampleSvg () { 328 | this.fs.copy( 329 | this.templatePath('assets/icons/react.svg'), 330 | this.destinationPath(this.paths.src.icons + '/react.svg') 331 | ) 332 | } 333 | 334 | copyHeadFiles () { 335 | this.fs.copy( 336 | this.templatePath('assets/head/favico.ico'), 337 | this.destinationPath(this.paths.src.head + '/favico.ico') 338 | ) 339 | this.fs.copy( 340 | this.templatePath('assets/head/favicon.png'), 341 | this.destinationPath(this.paths.src.head + '/favicon.png') 342 | ) 343 | this.fs.copyTpl( 344 | this.templatePath('assets/head/manifest.json.ejs'), 345 | this.destinationPath(this.paths.src.head + '/manifest.json'), 346 | { 347 | projectName: this.options.projectName 348 | } 349 | ) 350 | } 351 | 352 | writeHtmlFiles () { 353 | if (this.options.markupLanguage === 'html') { 354 | for (var i = 1; i < this.options.qtyScreens + 1; i++) { 355 | if (i === 1) { 356 | this.fs.copyTpl( 357 | this.templatePath('markup/_screen.' + this.options.markupLanguage + '.ejs'), 358 | this.destinationPath(this.paths.src.markup + '/index.html'), 359 | { 360 | screenNumber: i, 361 | projectName: this.options.projectName, 362 | frontEndFramework: this.options.frontEndFramework, 363 | jQuery: this.options.jQuery 364 | } 365 | ) 366 | } else { 367 | this.fs.copyTpl( 368 | this.templatePath('markup/_screen.' + this.options.markupLanguage + '.ejs'), 369 | this.destinationPath(this.paths.src.markup + '/screen-' + i + '.' + this.options.markupLanguage), 370 | { 371 | screenNumber: i, 372 | projectName: this.options.projectName, 373 | frontEndFramework: this.options.frontEndFramework, 374 | jQuery: this.options.jQuery 375 | } 376 | ) 377 | } 378 | } 379 | } 380 | } 381 | 382 | writePugFiles () { 383 | if (this.options.markupLanguage === 'pug') { 384 | for (var i = 1; i < this.options.qtyScreens + 1; i++) { 385 | if (i === 1) { 386 | this.fs.copyTpl( 387 | this.templatePath('markup/pug/_screen.' + this.options.markupLanguage), 388 | this.destinationPath(this.paths.src.markup + '/pug/index.pug'), 389 | { 390 | screenNumber: i, 391 | projectName: this.options.projectName, 392 | clientId: this.options.clientId, 393 | projectId: this.options.projectId, 394 | frontEndFramework: this.options.frontEndFramework, 395 | jQuery: this.options.jQuery 396 | } 397 | ) 398 | } else { 399 | this.fs.copyTpl( 400 | this.templatePath('markup/pug/_screen.' + this.options.markupLanguage), 401 | this.destinationPath(this.paths.src.markup + '/pug/screen-' + i + '.' + this.options.markupLanguage), 402 | { 403 | screenNumber: i, 404 | projectName: this.options.projectName, 405 | clientId: this.options.clientId, 406 | projectId: this.options.projectId, 407 | frontEndFramework: this.options.frontEndFramework, 408 | jQuery: this.options.jQuery 409 | } 410 | ) 411 | } 412 | } 413 | this.fs.copyTpl( 414 | this.templatePath('markup/pug/layouts/layout-primary.pug.ejs'), 415 | this.destinationPath(this.paths.src.markup + '/pug/layouts/layout-primary.pug'), 416 | { 417 | screenNumber: i, 418 | projectName: this.options.projectName, 419 | frontEndFramework: this.options.frontEndFramework, 420 | jQuery: this.options.jQuery 421 | } 422 | ) 423 | this.fs.copy( 424 | this.templatePath('markup/pug/layouts/general/**/*'), 425 | this.destinationPath(this.paths.src.markup + '/pug/layouts/general') 426 | ) 427 | this.fs.copy( 428 | this.templatePath('markup/pug/layouts/includes/**/*'), 429 | this.destinationPath(this.paths.src.markup + '/pug/layouts/includes') 430 | ) 431 | } 432 | } 433 | 434 | writeBaseStyles () { 435 | const styles = filesToAssert.scss 436 | 437 | styles.forEach(file => { 438 | this.fs.copy( 439 | this.templatePath(file), 440 | this.destinationPath(`src/assets/${file}`) 441 | ) 442 | }) 443 | 444 | for (var i = 1; i < this.options.qtyScreens + 1; i++) { 445 | this.fs.copyTpl( 446 | this.templatePath('styles/main/screens/_screen.scss'), 447 | this.destinationPath(this.paths.src.styles + '/main/screens/screen_' + i + '.scss'), { 448 | screenNumber: i, 449 | projectName: this.options.projectName 450 | } 451 | ) 452 | } 453 | } 454 | 455 | writeBaseScriptsFiles () { 456 | this.log(chalk.yellow('Copying js main file.')) 457 | this.fs.copyTpl( 458 | this.templatePath('scripts/app.js'), 459 | this.destinationPath(this.paths.src.scripts + '/app.js'), { 460 | projectName: this.options.projectName, 461 | frontEndFramework: this.options.frontEndFramework 462 | } 463 | ) 464 | this.fs.copyTpl( 465 | this.templatePath('scripts/index.js.ejs'), 466 | this.destinationPath(this.paths.src.scripts + '/index.js'), { 467 | projectName: this.options.projectName, 468 | frontEndFramework: this.options.frontEndFramework, 469 | jQuery: this.options.jQuery 470 | } 471 | ) 472 | 473 | if (this.options.frontEndFramework) { 474 | this.fs.copyTpl( 475 | this.templatePath('scripts/framework.js.ejs'), 476 | this.destinationPath(this.paths.src.scripts + '/framework.js'), { 477 | projectName: this.options.projectName, 478 | frontEndFramework: this.options.frontEndFramework, 479 | jQuery: this.options.jQuery 480 | } 481 | ) 482 | } 483 | } 484 | 485 | writeBaseGulpFiles () { 486 | this.log(chalk.yellow('Copying gulpfile.')) 487 | this.fs.copyTpl( 488 | this.templatePath('gulp/gulpfile.js.ejs'), 489 | this.destinationPath('gulpfile.js'), { 490 | paths: this.paths, 491 | frontEndFramework: this.options.frontEndFramework, 492 | jQuery: this.options.jQuery, 493 | markupLanguage: this.options.markupLanguage 494 | } 495 | ) 496 | 497 | this.log(chalk.yellow('Copying gulpfile config file.')) 498 | this.fs.copyTpl( 499 | this.templatePath('gulp/config.js.ejs'), 500 | this.destinationPath(this.paths.src.gulp + '/config.js'), { 501 | paths: this.paths, 502 | markupLanguage: this.options.markupLanguage, 503 | frontEndFramework: this.options.frontEndFramework, 504 | jQuery: this.options.jQuery 505 | } 506 | ) 507 | 508 | const tasks = [ 509 | 'common/cssModulesWrite', 510 | 'common/fonts', 511 | 'common/scripts', 512 | 'common/styles', 513 | 'development/serve', 514 | 'production/minifyStyles', 515 | 'production/purify', 516 | 'production/styles-production', 517 | 'production/zip' 518 | ] 519 | 520 | const templateTasks = [ 521 | 'common/markup', 522 | 'common/static', 523 | 'development/watch' 524 | ] 525 | 526 | tasks.forEach(file => 527 | this.fs.copy( 528 | this.templatePath(`gulp/${file}.js`), 529 | this.destinationPath(`gulp/${file}.js`) 530 | ) 531 | ) 532 | 533 | templateTasks.forEach(file => 534 | this.fs.copyTpl( 535 | this.templatePath(`gulp/${file}.js.ejs`), 536 | this.destinationPath(`gulp/${file}.js`), { 537 | paths: this.paths, 538 | markupLanguage: this.options.markupLanguage, 539 | clientId: this.options.clientId, 540 | projectId: this.options.projectId, 541 | frontEndFramework: this.options.frontEndFramework, 542 | jQuery: this.options.jQuery 543 | } 544 | ) 545 | ) 546 | } 547 | 548 | writeProjectConfigFile () { 549 | var configJson = { 550 | 'projectName': this.options.projectName, 551 | 'qtyScreens': this.options.qtyScreens, 552 | 'markupLanguage': this.options.markupLanguage, 553 | 'frontEndFramework': this.options.frontEndFramework, 554 | 'jQuery': this.options.jQuery, 555 | 'generatedBy': 'Pixel2HTML', 556 | 'generatorVersion': pkg.version, 557 | 'generatedAt': moment().format() 558 | } 559 | 560 | this.fs.writeJSON('./.project.conf', configJson) 561 | } 562 | 563 | installWebpackSituations () { 564 | const webpackFiles = [ 565 | 'commonPlugins.js', 566 | 'debugPlugins.js', 567 | 'developmentPlugins.js', 568 | 'paths.js', 569 | 'productionPlugins.js' 570 | ] 571 | 572 | // Work smart not hard 573 | webpackFiles.map(file => { 574 | this.fs.copy( 575 | this.templatePath(`webpack/${file}`), 576 | this.destinationPath(`webpack/${file}`) 577 | ) 578 | }) 579 | } 580 | 581 | installDependencies () { 582 | this.options.yarn 583 | ? this.yarnInstall() 584 | : this.log('Skipping yarn install') 585 | } 586 | 587 | eslintJs () { 588 | const jsFilter = filter(['**/*.js'], { restore: true }) 589 | const jsonFilter = filter(['**/*.json'], { restore: true }) 590 | this.registerTransformStream([ 591 | jsonFilter, 592 | prettify({ 593 | indent_size: 2 594 | }), 595 | jsonFilter.restore 596 | ]) 597 | this.registerTransformStream([ 598 | jsFilter, 599 | eslint({ 600 | fix: true 601 | }), 602 | eslint.format(), 603 | jsFilter.restore 604 | ]) 605 | } 606 | } 607 | 608 | module.exports = PixelGenerator 609 | --------------------------------------------------------------------------------