diff --git a/{{cookiecutter.project_slug}}/.gitignore b/{{cookiecutter.project_slug}}/.gitignore
index 6a0a3029e..710ba625d 100644
--- a/{{cookiecutter.project_slug}}/.gitignore
+++ b/{{cookiecutter.project_slug}}/.gitignore
@@ -79,3 +79,4 @@ staticfiles/
.cache/
+{{ cookiecutter.project_slug }}/static/build/
diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py
index 274e28067..5b07086da 100644
--- a/{{cookiecutter.project_slug}}/config/settings/base.py
+++ b/{{cookiecutter.project_slug}}/config/settings/base.py
@@ -184,9 +184,10 @@ STATIC_ROOT = str(ROOT_DIR('staticfiles'))
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = '/static/'
+_STATIC_BUILD_ROOT_DIR_NAME = 'build'
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = [
- str(APPS_DIR.path('static')),
+ (_STATIC_BUILD_ROOT_DIR_NAME, str(APPS_DIR.path('static').path(_STATIC_BUILD_ROOT_DIR_NAME))),
]
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
diff --git a/{{cookiecutter.project_slug}}/gulpfile.js b/{{cookiecutter.project_slug}}/gulpfile.js
index b67a7bee9..ea5f5e29a 100644
--- a/{{cookiecutter.project_slug}}/gulpfile.js
+++ b/{{cookiecutter.project_slug}}/gulpfile.js
@@ -1,105 +1,161 @@
+const gulp = require('gulp')
+const pump = require('pump')
+const sass = require('gulp-sass')
+const pjson = require('./package.json')
+const autoprefixer = require('gulp-autoprefixer')
+const cleanCSS = require('gulp-clean-css')
+const rename = require('gulp-rename')
+const pixrem = require('gulp-pixrem')
+const concat = require('gulp-concat')
+const uglify = require('gulp-uglify')
+const imagemin = require('gulp-imagemin')
+const clean = require('gulp-clean')
+const spawn = require('child_process').spawn
+const runSequence = require('run-sequence')
+const browserSync = require('browser-sync').create()
+const reload = browserSync.reload
-////////////////////////////////
- //Setup//
-////////////////////////////////
+const pathsConfig = function (appName) {
+ this.paths = {}
-// Plugins
-var gulp = require('gulp'),
- pjson = require('./package.json'),
- gutil = require('gulp-util'),
- sass = require('gulp-sass'),
- autoprefixer = require('gulp-autoprefixer'),
- cssnano = require('gulp-cssnano'),
- rename = require('gulp-rename'),
- del = require('del'),
- plumber = require('gulp-plumber'),
- pixrem = require('gulp-pixrem'),
- uglify = require('gulp-uglify'),
- imagemin = require('gulp-imagemin'),
- spawn = require('child_process').spawn,
- runSequence = require('run-sequence'),
- browserSync = require('browser-sync').create(),
- reload = browserSync.reload;
+ this.paths['app'] = './' + (appName || pjson.name)
+ this.paths['static'] = this.paths['app'] + '/static'
-// Relative paths function
-var pathsConfig = function (appName) {
- this.app = "./" + (appName || pjson.name);
+ this.paths['build'] = this.paths['static'] + '/build'
- return {
- 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',
- }
-};
+ this.paths['buildImages'] = this.paths['build'] + '/images'
+ this.paths['images'] = this.paths['static'] + '/images'
+ this.paths['images_files'] = this.paths['images'] + '/*'
+ this.paths['buildImagesFavicons'] = this.paths['buildImages'] + '/favicons'
+ this.paths['imagesFavicons'] = this.paths['images'] + '/favicons'
+ this.paths['imagesFavicons_files'] = this.paths['imagesFavicons'] + '/*'
-var paths = pathsConfig();
+ this.paths['build_scriptsFileName'] = 'scripts.js'
+ this.paths['scripts'] = this.paths['static'] + '/scripts'
+ this.paths['scriptsJs'] = this.paths['scripts'] + '/js'
+ this.paths['scriptsJs_files'] = this.paths['scriptsJs'] + '/*.js'
-////////////////////////////////
- //Tasks//
-////////////////////////////////
+ this.paths['build_stylesFileName'] = 'styles.css'
+ this.paths['styles'] = this.paths['static'] + '/styles'
+ this.paths['stylesSass'] = this.paths['styles'] + '/sass'
+ this.paths['stylesSass_files'] = this.paths['stylesSass'] + '/*.scss'
+ this.paths['stylesCss'] = this.paths['styles'] + '/css'
+ this.paths['stylesCss_files'] = this.paths['stylesCss'] + '/*.css'
-// Styles autoprefixing and minification
-gulp.task('styles', function() {
- return gulp.src(paths.sass + '/project.scss')
- .pipe(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
- .pipe(gulp.dest(paths.css))
- .pipe(rename({ suffix: '.min' }))
- .pipe(cssnano()) // Minifies the result
- .pipe(gulp.dest(paths.css));
-});
+ this.paths['templates'] = this.paths['app'] + '/templates'
+ this.paths['templates_files'] = this.paths['templates'] + '/*.html'
-// Javascript minification
-gulp.task('scripts', function() {
- return gulp.src(paths.js + '/project.js')
- .pipe(plumber()) // Checks for errors
- .pipe(uglify()) // Minifies the js
- .pipe(rename({ suffix: '.min' }))
- .pipe(gulp.dest(paths.js));
-});
+ return this.paths
+}
+const paths = pathsConfig()
-// Image compression
-gulp.task('imgCompression', function(){
- return gulp.src(paths.images + '/*')
- .pipe(imagemin()) // Compresses PNG, JPEG, GIF and SVG images
- .pipe(gulp.dest(paths.images))
-});
+// region scripts
+gulp.task('favicons-images', function (cb) {
+ pump([gulp.src(paths.imagesFavicons_files),
+ gulp.dest(paths.buildImagesFavicons)],
+ cb)
+})
-// Run django server
-gulp.task('runServer', function(cb) {
- var cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'});
- cmd.on('close', function(code) {
- console.log('runServer exited with code ' + code);
- cb(code);
- });
-});
+gulp.task('nonfavicons-images', function (cb) {
+ pump([gulp.src(paths.images_files),
+ imagemin(),
+ gulp.dest(paths.buildImages)],
+ cb)
+})
-// Browser sync server for live reload
-gulp.task('browserSync', function() {
- browserSync.init(
- [paths.css + "/*.css", paths.js + "*.js", paths.templates + '*.html'], {
- proxy: "localhost:8000"
- });
-});
+gulp.task('images', function () {
+ runSequence(['favicons-images', 'nonfavicons-images'])
+})
+// endregion
-// Watch
-gulp.task('watch', function() {
+// region scripts
+gulp.task('js-scripts', function (cb) {
+ pump([gulp.src(paths.scriptsJs_files),
+ concat(paths.build_scriptsFileName),
+ uglify(),
+ rename({suffix: '.min'}),
+ gulp.dest(paths.build)],
+ cb)
+})
- gulp.watch(paths.sass + '/*.scss', ['styles']);
- gulp.watch(paths.js + '/*.js', ['scripts']).on("change", reload);
- gulp.watch(paths.images + '/*', ['imgCompression']);
- gulp.watch(paths.templates + '/**/*.html').on("change", reload);
+gulp.task('scripts', function () {
+ runSequence('js-scripts')
+})
+// endregion
-});
+// region styles
+gulp.task('sass-styles', function (cb) {
+ pump([gulp.src(paths.stylesSass_files),
+ sass(),
+ gulp.dest(paths.stylesCss)],
+ cb
+ )
+})
-// Default task
-gulp.task('default', function() {
- runSequence(['styles', 'scripts', 'imgCompression'], 'runServer', 'browserSync', 'watch');
-});
+gulp.task('css-styles', function (cb) {
+ pump([gulp.src(paths.stylesCss_files),
+ concat(paths.build_stylesFileName),
+ autoprefixer({browsers: ['last 2 versions']}),
+ pixrem(),
+ cleanCSS({rebaseTo: '../../'}),
+ rename({suffix: '.min'}),
+ gulp.dest(paths.build)],
+ cb)
+})
+
+gulp.task('styles', function () {
+ runSequence('sass-styles', 'css-styles')
+})
+// endregion
+
+// region manage.py
+gulp.task('migrate', function (cb) {
+ const cmd = spawn('python', ['manage.py', 'migrate'], {stdio: 'inherit'})
+ cmd.on(close, function (code) {
+ console.log('runServerPlus exited with code ' + code)
+ cb(code)
+ })
+})
+
+gulp.task('runServerPlus', function (cb) {
+ const cmd = spawn('python', ['manage.py', 'runserver_plus'], {stdio: 'inherit'})
+ cmd.on(close, function (code) {
+ console.log('runServerPlus exited with code ' + code)
+ cb(code)
+ })
+})
+// endregion
+
+gulp.task('browserSync', function () {
+ browserSync.init(
+ [paths.images_files, paths.scriptsJs_files, paths.stylesCss_files, paths.templates_files], {
+ proxy: 'localhost:8000'
+ })
+})
+
+gulp.task('build', function () {
+ runSequence(['images', 'scripts', 'styles'])
+})
+
+gulp.task('clean-build', function (cb) {
+ pump([gulp.src(paths.build),
+ clean()],
+ cb)
+})
+
+gulp.task('default', function () {
+ runSequence('build', 'runServerPlus', 'browserSync')
+})
+
+gulp.task('default-migrate', function () {
+ runSequence('build', 'migrate', 'runServerPlus', 'browserSync')
+})
+
+gulp.task('watch', ['default'], function () {
+ gulp.watch(paths.images_files, ['images'])
+ gulp.watch(paths.scriptsJs_files, ['js-scripts']).on('change', reload)
+ gulp.watch(paths.stylesSass_files, ['sass-styles'])
+ gulp.watch(paths.stylesCss_files, ['css-styles'])
+ gulp.watch(paths.templates_files).on('change', reload)
+})
diff --git a/{{cookiecutter.project_slug}}/package.json b/{{cookiecutter.project_slug}}/package.json
index 0c8af4272..a47fbdff9 100644
--- a/{{cookiecutter.project_slug}}/package.json
+++ b/{{cookiecutter.project_slug}}/package.json
@@ -16,22 +16,28 @@
"pixrem": "~1.3.1",
"time-grunt": "~1.2.1"
{% elif cookiecutter.js_task_runner == 'Gulp' %}
- "browser-sync": "^2.14.0",
- "del": "^2.2.2",
+ "browser-sync": "^2.18.8",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.1",
- "gulp-cssnano": "^2.1.2",
- "gulp-imagemin": "^3.0.3",
+ "gulp-clean": "^0.3.2",
+ "gulp-clean-css": "^3.0.4",
+ "gulp-concat": "^2.6.1",
+ "gulp-imagemin": "^3.1.1",
"gulp-pixrem": "^1.0.0",
- "gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
- "gulp-sass": "^2.3.2",
- "gulp-uglify": "^2.0.0",
- "gulp-util": "^3.0.7",
- "run-sequence": "^1.2.2"
+ "gulp-sass": "^3.1.0",
+ "gulp-uglify": "^2.1.2",
+ "npm-check-updates": "^2.10.3",
+ "pump": "^1.0.2",
+ "run-sequence": "^1.2.2",
+ "standard": "^9.0.2",
+ "npm-check": "^5.4.0"
{% endif %}
},
"engines": {
"node": ">=0.8.0"
+ },
+ "scripts": {
+ "test": "standard"
}
}
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/.gitkeep b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/css/project.css b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/css/project.css
deleted file mode 100644
index 5f23c427a..000000000
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/css/project.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/* These styles are generated from project.scss. */
-
-.alert-debug {
- color: black;
- background-color: white;
- border-color: #d6e9c6;
-}
-
-.alert-error {
- color: #b94a48;
- background-color: #f2dede;
- border-color: #eed3d7;
-}
-
-/* This is a fix for the bootstrap4 alpha release */
-@media (max-width: 47.9em) {
- .navbar-nav .nav-item {
- float: none;
- width: 100%;
- display: inline-block;
- }
-
- .navbar-nav .nav-item + .nav-item {
- margin-left: 0;
- }
-
- .nav.navbar-nav.pull-xs-right {
- float: none !important;
- }
-}
-
-/* Display django-debug-toolbar.
- See https://github.com/django-debug-toolbar/django-debug-toolbar/issues/742
- and https://github.com/pydanny/cookiecutter-django/issues/317
-*/
-[hidden][style="display: block;"] {
- display: block !important;
-}
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/images/.gitkeep b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/images/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/js/project.js b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/js/project.js
deleted file mode 100644
index 91ab9e2da..000000000
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/js/project.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Project specific Javascript goes here. */
-
-/*
-Formatting hack to get around crispy-forms unfortunate hardcoding
-in helpers.FormHelper:
-
- if template_pack == 'bootstrap4':
- grid_colum_matcher = re.compile('\w*col-(xs|sm|md|lg|xl)-\d+\w*')
- using_grid_layout = (grid_colum_matcher.match(self.label_class) or
- grid_colum_matcher.match(self.field_class))
- if using_grid_layout:
- items['using_grid_layout'] = True
-
-Issues with the above approach:
-
-1. Fragile: Assumes Bootstrap 4's API doesn't change (it does)
-2. Unforgiving: Doesn't allow for any variation in template design
-3. Really Unforgiving: No way to override this behavior
-4. Undocumented: No mention in the documentation, or it's too hard for me to find
-*/
-$('.form-group').removeClass('row');
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/scripts/.gitkeep b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/scripts/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/scripts/js/project.js b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/scripts/js/project.js
new file mode 100644
index 000000000..360177996
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/scripts/js/project.js
@@ -0,0 +1,21 @@
+/* Project specific Javascript goes here. */
+
+/*
+ Formatting hack to get around crispy-forms unfortunate hardcoding
+ in helpers.FormHelper:
+
+ if template_pack == 'bootstrap4':
+ grid_colum_matcher = re.compile('\w*col-(xs|sm|md|lg|xl)-\d+\w*')
+ using_grid_layout = (grid_colum_matcher.match(self.label_class) or
+ grid_colum_matcher.match(self.field_class))
+ if using_grid_layout:
+ items['using_grid_layout'] = True
+
+ Issues with the above approach:
+
+ 1. Fragile: Assumes Bootstrap 4's API doesn't change (it does)
+ 2. Unforgiving: Doesn't allow for any variation in template design
+ 3. Really Unforgiving: No way to override this behavior
+ 4. Undocumented: No mention in the documentation, or it's too hard for me to find
+ */
+$('.form-group').removeClass('row')
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/styles/.gitkeep b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/styles/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/styles/css/project.css b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/styles/css/project.css
new file mode 100644
index 000000000..6b20fb3dc
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/styles/css/project.css
@@ -0,0 +1,26 @@
+.alert-debug {
+ background-color: #fff;
+ border-color: #d6e9c6;
+ color: #000; }
+
+.alert-error {
+ background-color: #f2dede;
+ border-color: #eed3d7;
+ color: #b94a48; }
+
+.navbar {
+ border-radius: 0px; }
+
+@media (max-width: 47.9em) {
+ .navbar-nav .nav-item {
+ display: inline-block;
+ float: none;
+ width: 100%; }
+ .navbar-nav .nav-item + .nav-item {
+ margin-left: 0; }
+ .nav.navbar-nav.pull-xs-right {
+ float: none !important; } }
+
+[hidden][style="display: block;"] {
+ display: block !important; }
+
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/styles/sass/project.scss
similarity index 95%
rename from {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss
rename to {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/styles/sass/project.scss
index 54632b2d6..cc30bfcb6 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/styles/sass/project.scss
@@ -1,8 +1,7 @@
-
// project specific CSS goes here
////////////////////////////////
- //Variables//
+//Variables//
////////////////////////////////
// Alert colors
@@ -15,7 +14,7 @@ $dark-pink: #eed3d7;
$red: #b94a48;
////////////////////////////////
- //Alerts//
+//Alerts//
////////////////////////////////
// bootstrap alert CSS, translated to the django-standard levels of
@@ -34,7 +33,7 @@ $red: #b94a48;
}
////////////////////////////////
- //Navbar//
+//Navbar//
////////////////////////////////
// This is a fix for the bootstrap4 alpha release
@@ -60,7 +59,7 @@ $red: #b94a48;
}
////////////////////////////////
- //Django Toolbar//
+//Django Toolbar//
////////////////////////////////
// Display django-debug-toolbar.
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html
index e947da5b8..cd369e28f 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html
@@ -20,7 +20,7 @@
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress css %}{% endraw %}{% endif %}{% raw %}
-
+
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
{% endblock %}
@@ -97,7 +97,7 @@
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
-
+
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
{% endblock javascript %}