diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index 5a0cffe6..d1d36324 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -73,7 +73,9 @@ js_task_runner [1] 3. None custom_bootstrap_compilation [n] - If you use Grunt, scaffold out recompiling Bootstrap as as task. (Useful for letting you change Bootstrap variables in real time.) Consult project README for more details. + Scaffold out recompiling Bootstrap as as task, with Gulp_ or Grunt_. + Useful for letting you change Bootstrap variables in real time. + Consult project README for more details. open_source_license [1] Select a software license for the project. The choices are: diff --git a/{{cookiecutter.project_slug}}/Gruntfile.js b/{{cookiecutter.project_slug}}/Gruntfile.js index 6900c4e0..15384c67 100644 --- a/{{cookiecutter.project_slug}}/Gruntfile.js +++ b/{{cookiecutter.project_slug}}/Gruntfile.js @@ -61,7 +61,7 @@ module.exports = function (grunt) { options: { outputStyle: 'nested', {% if cookiecutter.custom_bootstrap_compilation == 'y' %} - includePaths: ['bower_components/bootstrap-sass/assets/stylesheets/bootstrap/'], + includePaths: ['node_modules/bootstrap/scss'], {% endif %} sourceMap: false, precision: 10 @@ -74,7 +74,7 @@ module.exports = function (grunt) { options: { outputStyle: 'compressed', {% if cookiecutter.custom_bootstrap_compilation == 'y' %} - includePaths: ['bower_components/bootstrap-sass/assets/stylesheets/bootstrap/'], + includePaths: ['node_modules/bootstrap/scss'], {% endif %} sourceMap: false, precision: 10 diff --git a/{{cookiecutter.project_slug}}/README.rst b/{{cookiecutter.project_slug}}/README.rst index 06dd82ed..dc3495d5 100644 --- a/{{cookiecutter.project_slug}}/README.rst +++ b/{{cookiecutter.project_slug}}/README.rst @@ -137,8 +137,16 @@ See detailed `cookiecutter-django Docker documentation`_. Custom Bootstrap Compilation ^^^^^^ -To get automatic Bootstrap recompilation with variables of your choice, install bootstrap sass (`bower install bootstrap-sass`) and tweak your variables in `static/sass/custom_bootstrap_vars`. +The generated CSS is set up with automatic Bootstrap recompilation with variables of your choice. +Bootstrap v4 is installed using npm and customised by tweaking your variables in ``static/sass/custom_bootstrap_vars``. -(You can find a list of available variables [in the bootstrap-sass source](https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/_variables.scss), or get explanations on them in the [Bootstrap docs](https://getbootstrap.com/customize/).) +You can find a list of available variables `in the bootstrap source`_, or get explanations on them in the `Bootstrap docs`_. + +{% if cookiecutter.js_task_runner == 'Gulp' %} +Bootstrap's javascript as well as its dependencies is concatenated into a single file: ``static/js/vendors.js``. +{% endif %} + +.. _in the bootstrap source: https://github.com/twbs/bootstrap/blob/v4-dev/scss/_variables.scss +.. _Bootstrap docs: https://getbootstrap.com/docs/4.0/getting-started/theming/ {% endif %} diff --git a/{{cookiecutter.project_slug}}/gulpfile.js b/{{cookiecutter.project_slug}}/gulpfile.js index 594fa090..bb18a535 100644 --- a/{{cookiecutter.project_slug}}/gulpfile.js +++ b/{{cookiecutter.project_slug}}/gulpfile.js @@ -10,6 +10,9 @@ var gulp = require('gulp'), sass = require('gulp-sass'), autoprefixer = require('gulp-autoprefixer'), cssnano = require('gulp-cssnano'), + {% if cookiecutter.custom_bootstrap_compilation == 'y' %} + concat = require('gulp-concat'), + {% endif %} rename = require('gulp-rename'), del = require('del'), plumber = require('gulp-plumber'), @@ -25,15 +28,24 @@ var gulp = require('gulp'), // Relative paths function var pathsConfig = function (appName) { this.app = "./" + (appName || pjson.name); + var vendorsRoot = 'node_modules/'; return { + {% if cookiecutter.custom_bootstrap_compilation == 'y' %} + bootstrapSass: vendorsRoot + '/bootstrap/scss', + vendorsJs: [ + vendorsRoot + 'jquery/dist/jquery.slim.js', + vendorsRoot + 'popper.js/dist/umd/popper.js', + vendorsRoot + 'bootstrap/dist/js/bootstrap.js' + ], + {% endif %} app: this.app, templates: this.app + '/templates', css: this.app + '/static/css', sass: this.app + '/static/sass', fonts: this.app + '/static/fonts', images: this.app + '/static/images', - js: this.app + '/static/js', + js: this.app + '/static/js' } }; @@ -45,8 +57,15 @@ var paths = pathsConfig(); // Styles autoprefixing and minification gulp.task('styles', function() { - return gulp.src(paths.sass + '/*.scss') - .pipe(sass().on('error', sass.logError)) + return gulp.src(paths.sass + '/project.scss') + .pipe(sass({ + includePaths: [ + {% if cookiecutter.custom_bootstrap_compilation == 'y' %} + paths.bootstrapSass, + {% endif %} + paths.sass + ] + }).on('error', sass.logError)) .pipe(plumber()) // Checks for errors .pipe(autoprefixer({browsers: ['last 2 versions']})) // Adds vendor prefixes .pipe(pixrem()) // add fallbacks for rem units @@ -65,6 +84,20 @@ gulp.task('scripts', function() { .pipe(gulp.dest(paths.js)); }); + +{% if cookiecutter.custom_bootstrap_compilation == 'y' %} +// Vendor Javascript minification +gulp.task('vendor-scripts', function() { + return gulp.src(paths.vendorsJs) + .pipe(concat('vendors.js')) + .pipe(gulp.dest(paths.js)) + .pipe(plumber()) // Checks for errors + .pipe(uglify()) // Minifies the js + .pipe(rename({ suffix: '.min' })) + .pipe(gulp.dest(paths.js)); +}); +{% endif %} + // Image compression gulp.task('imgCompression', function(){ return gulp.src(paths.images + '/*') @@ -101,5 +134,5 @@ gulp.task('watch', function() { // Default task gulp.task('default', function() { - runSequence(['styles', 'scripts', 'imgCompression'], ['runServer', 'browserSync', 'watch']); + runSequence(['styles', 'scripts', {% if cookiecutter.custom_bootstrap_compilation == 'y' %}'vendor-scripts', {% endif %}'imgCompression'], ['runServer', 'browserSync', 'watch']); }); diff --git a/{{cookiecutter.project_slug}}/package.json b/{{cookiecutter.project_slug}}/package.json index 0c8af427..a37d73bf 100644 --- a/{{cookiecutter.project_slug}}/package.json +++ b/{{cookiecutter.project_slug}}/package.json @@ -5,6 +5,9 @@ "devDependencies": { {% if cookiecutter.js_task_runner == 'Grunt' %} "autoprefixer-core": "~5.2.1", + {% if cookiecutter.custom_bootstrap_compilation == 'y' %} + "bootstrap": "^4.0.0", + {% endif %} "connect-livereload": "~0.3.2", "cssnano": "~2.1.0", "grunt": "~0.4.5", @@ -12,14 +15,26 @@ "grunt-contrib-watch": "~0.6.1", "grunt-postcss": "~0.5.5", "grunt-sass": "~1.0.0", + {% if cookiecutter.custom_bootstrap_compilation == 'y' %} + "jquery": "^3.2.1-slim", + {% endif %} "load-grunt-tasks": "~3.2.0", "pixrem": "~1.3.1", + {% if cookiecutter.custom_bootstrap_compilation == 'y' %} + "popper.js": "^1.12.3", + {% endif %} "time-grunt": "~1.2.1" {% elif cookiecutter.js_task_runner == 'Gulp' %} + {% if cookiecutter.custom_bootstrap_compilation == 'y' %} + "bootstrap": "^4.0.0", + {% endif %} "browser-sync": "^2.14.0", "del": "^2.2.2", "gulp": "^3.9.1", "gulp-autoprefixer": "^3.1.1", + {% if cookiecutter.custom_bootstrap_compilation == 'y' %} + "gulp-concat": "^2.6.1", + {% endif %} "gulp-cssnano": "^2.1.2", "gulp-imagemin": "^3.0.3", "gulp-pixrem": "^1.0.0", @@ -28,6 +43,10 @@ "gulp-sass": "^2.3.2", "gulp-uglify": "^2.0.0", "gulp-util": "^3.0.7", + {% if cookiecutter.custom_bootstrap_compilation == 'y' %} + "jquery": "^3.2.1-slim", + "popper.js": "^1.12.3", + {% endif %} "run-sequence": "^1.2.2" {% endif %} }, diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss index 6e701f29..3ba2e55a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss @@ -1,54 +1,6 @@ {% if cookiecutter.custom_bootstrap_compilation == 'y' %} -@import "variables"; @import "custom_bootstrap_vars"; -@import "mixins"; - -// Reset and dependencies -@import "normalize"; -@import "print"; -@import "glyphicons"; - -// Core CSS -@import "scaffolding"; -@import "type"; -@import "code"; -@import "grid"; -@import "tables"; -@import "forms"; -@import "buttons"; - -// Components -@import "component-animations"; -@import "dropdowns"; -@import "button-groups"; -@import "input-groups"; -@import "navs"; -@import "navbar"; -@import "breadcrumbs"; -@import "pagination"; -@import "pager"; -@import "labels"; -@import "badges"; -@import "jumbotron"; -@import "thumbnails"; -@import "alerts"; -@import "progress-bars"; -@import "media"; -@import "list-group"; -@import "panels"; -@import "responsive-embed"; -@import "wells"; -@import "close"; - -// Components w/ JavaScript -@import "modals"; -@import "tooltip"; -@import "popovers"; -@import "carousel"; - -// Utility classes -@import "utilities"; -@import "responsive-utilities"; +@import "bootstrap"; {% endif %} diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html index 6fdc1798..a45de763 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html @@ -14,13 +14,19 @@ {% block css %} + {% endraw %}{% if cookiecutter.custom_bootstrap_compilation == "n" %}{% raw %} + {% endraw %}{% endif %}{% raw %} {% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress css %}{% endraw %}{% endif %}{% raw %} + {% endraw %}{% if cookiecutter.js_task_runner == "Gulp" %}{% raw %} + + {% endraw %}{% else %}{% raw %} + {% endraw %}{% endif %}{% raw %} {% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %} {% endblock %} @@ -88,12 +94,19 @@ ================================================== --> {% block javascript %} + {% endraw %}{% if cookiecutter.custom_bootstrap_compilation == "y" and cookiecutter.js_task_runner == "Gulp" %}{% raw %} + + {% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %} + + {% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %} + {% endraw %}{% else %}{% raw %} + {% endraw %}{% endif %}{% raw %} {% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}