diff --git a/default.ascx b/default.ascx index 7dcf1d8..46e16ae 100644 --- a/default.ascx +++ b/default.ascx @@ -6,41 +6,17 @@
-
-
-
-
-
-
-
- -
-
-
-
-
+ +
-
-
-
-
- -
-
-
-
-
-
+
-
-
-
-
-
+
+
diff --git a/gulpfile.js b/gulpfile.js index 6141ffb..e0e752e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,8 +2,11 @@ var bs = require('browser-sync').create(), gulp = require('gulp'), autoprefixer = require('gulp-autoprefixer'), jshint = require('gulp-jshint'), - sass = require('gulp-sass'), + sass = require('gulp-sass')(require('sass')), imagemin = require('gulp-imagemin'), + modernizr = require('gulp-modernizr'), + imwebp = require('imagemin-webp'), + webp = require('gulp-webp'), rename = require('gulp-rename'), uglify = require('gulp-uglify'), notify = require('gulp-notify'), @@ -49,7 +52,7 @@ var paths = { dest: './dist/js/' }, images: { - src: './src/images/**/*.{jpg,jpeg,png,gif,svg}', + src: './src/images/**/*.{jpg,jpeg,png,gif,svg,webp}', dest: './dist/images/' }, styles: { @@ -79,7 +82,7 @@ var paths = { dest: './temp/' }, zipelse: { - src: ['./menus/**/*', './partials/*', '*.{ascx,xml,html,htm}'], + src: ['./menus/**/*', './partials/*', '*.{ascx,xml,html,htm}', 'koi.json'], zipfile: 'else.zip', dest: './temp/' }, @@ -104,28 +107,28 @@ var paths = { function fontsInit() { return gulp.src(paths.fonts.src) .pipe(gulp.dest(paths.fonts.dest)) - .pipe(notify({message: '<%= file.relative %> distributed!', title : 'fontsInit', sound: false})); + .pipe(notify({message: '<%= file.relative %> distributed!', title : 'fontsInit'})); } // Copy fontawesome-free fonts from node_modules to dist/fonts function faFontsInit() { return gulp.src(paths.faFonts.src) .pipe(gulp.dest(paths.faFonts.dest)) - .pipe(notify({message: '<%= file.relative %> distributed!', title : 'faFontsInit', sound: false})); + .pipe(notify({message: '<%= file.relative %> distributed!', title : 'faFontsInit'})); } // Copy fontawesome-free CSS from node_modules to dist/css/fontawesome-free function faCssInit() { return gulp.src(paths.faCss.src) .pipe(gulp.dest(paths.faCss.dest)) - .pipe(notify({message: '<%= file.relative %> distributed!', title : 'faCssInit', sound: false})); + .pipe(notify({message: '<%= file.relative %> distributed!', title : 'faCssInit'})); } // Copy jquery.slimmenu.min.js from src/assets to dist/js function slimMenuInit() { return gulp.src(paths.slimMenu.src) .pipe(gulp.dest(paths.slimMenu.dest)) - .pipe(notify({message: '<%= file.relative %> distributed!', title : 'slimMenuInit', sound: false})); + .pipe(notify({message: '<%= file.relative %> distributed!', title : 'slimMenuInit'})); } // Compile normalize.css from node_modules and copy to dist/js @@ -136,15 +139,33 @@ function normalizeInit() { .pipe(rename({suffix: '.min'})) .pipe(autoprefixer()) .pipe(gulp.dest(paths.normalize.dest, { sourcemaps: '.' })) - .pipe(notify({message: '<%= file.relative %> compiled and distributed!', title : 'normalizeInit', sound: false})); + .pipe(notify({message: '<%= file.relative %> compiled and distributed!', title : 'normalizeInit'})); } // Copy bootstrap JS from node_modules to dist/js function bsJsInit() { return gulp.src(paths.bsJs.src) .pipe(gulp.dest(paths.bsJs.dest)) - .pipe(notify({message: '<%= file.relative %> distributed!', title : 'bsJsInit', sound: false})); + .pipe(notify({message: '<%= file.relative %> distributed!', title : 'bsJsInit'})); } + +// modernizr Init +function modernizrInit() { + return gulp.src(paths.scripts.src) + .pipe(modernizr({ + 'options': [ + 'setClasses' + ], + 'tests': [ + 'webp' + ] + })) + .pipe(uglify()) + .pipe(rename({suffix: '-custom.min'})) + .pipe(gulp.dest(paths.scripts.dest)) + .pipe(notify({message: '<%= file.relative %> distributed!', title : 'modernizrInit', sound: false})); +} + /*------------------------------------------------------*/ /* END INIT TASKS --------------------------------------*/ /*------------------------------------------------------*/ @@ -154,17 +175,34 @@ function bsJsInit() { /* IMAGE TASKS -----------------------------------------*/ /*------------------------------------------------------*/ // Optimize images and copy to dist/images -function images() { +function optimize() { return gulp.src(paths.images.src, {since: gulp.lastRun(images)}) - .pipe(imagemin({ - interlaced: true, - progressive: true, - optimizationLevel: 5, - svgoPlugins: [{removeViewBox: true}] - })) + .pipe(imagemin([ + imagemin.gifsicle({interlaced: true}), + imagemin.mozjpeg({quality: 75, progressive: true}), + imagemin.optipng({optimizationLevel: 5}), + imagemin.svgo({ + plugins: [ + {removeViewBox: true}, + {cleanupIDs: false} + ] + }) + ], { + plugins: imwebp({quality:75}) + } + )) .pipe(gulp.dest(paths.images.dest)) - .pipe(notify({message: '<%= file.relative %> optimized!', title : 'images', sound: false})); + .pipe(notify({message: '<%= file.relative %> optimized!', title : 'images'})); } + +// Make WebP versions of all images +function convert() { + return gulp.src(paths.images.src, {since: gulp.lastRun(images)}) + .pipe(webp()) + .pipe(gulp.dest(paths.images.dest)) + .pipe(notify({message: '<%= file.relative %> converted to webp!', title : 'images'})); +} + /*------------------------------------------------------*/ /* END IMAGE TASKS -------------------------------------*/ /*------------------------------------------------------*/ @@ -181,7 +219,7 @@ function styles() { .pipe(rename({suffix: '.min'})) .pipe(autoprefixer()) .pipe(gulp.dest(paths.styles.dest, { sourcemaps: '.' })) - .pipe(notify({message: '<%= file.relative %> compiled and distributed!', title : 'styles', sound: false})); + .pipe(notify({message: '<%= file.relative %> compiled and distributed!', title: 'styles'})); } /*------------------------------------------------------*/ /* END STYLES TASKS ------------------------------------*/ @@ -200,7 +238,7 @@ function scripts() { .pipe(gulp.dest(paths.scripts.dest, { sourcemaps: '.' })) .pipe(jshint.reporter('default')) .pipe(jshint.reporter('fail')) - .pipe(notify({ message : '<%= file.relative %> minified!', title : "scripts", sound: false})); + .pipe(notify({ message : '<%= file.relative %> minified!', title : "scripts"})); } /*------------------------------------------------------*/ /* END SCRIPTS TASKS -----------------------------------*/ @@ -214,7 +252,7 @@ function scripts() { function containers() { return gulp.src(paths.containers.src) .pipe(gulp.dest(paths.containers.dest)) - .pipe(notify({message: '<%= file.relative %> distributed!', title : 'containers', sound: false})); + .pipe(notify({message: '<%= file.relative %> distributed!', title : 'containers'})); } // Update manifest.dnn @@ -232,7 +270,7 @@ function manifest() { .pipe(replace(/(\\Skins\\)(.*?)(?=\\)/g, '\\Skins\\'+project)) .pipe(replace(/(\\Containers\\)(.*?)(?=\\)/g, '\\Containers\\'+project)) .pipe(gulp.dest(paths.manifest.dest)) - .pipe(notify({message: '<%= file.relative %> updated!', title : 'manifest', sound: false})); + .pipe(notify({message: '<%= file.relative %> updated!', title : 'manifest'})); } /*------------------------------------------------------*/ /* END DNN TASKS ---------------------------------------*/ @@ -246,7 +284,7 @@ function manifest() { function cleandist() { return gulp.src(paths.cleandist.src, { allowEmpty: true }) .pipe(clean()) - .pipe(notify({message: 'dist folder cleaned up!', title : 'cleandist', sound: false})); + .pipe(notify({message: 'dist folder cleaned up!', title : 'cleandist'})); } /*------------------------------------------------------*/ /* END MAINTENANCE TASKS -------------------------------*/ @@ -261,7 +299,7 @@ function zipdist() { return gulp.src(paths.zipdist.src) .pipe(zip(paths.zipdist.zipfile)) .pipe(gulp.dest(paths.zipdist.dest)) - .pipe(notify({message: '<%= file.relative %> temporarily created!', title : 'zipdist', sound: false})); + .pipe(notify({message: '<%= file.relative %> temporarily created!', title : 'zipdist'})); } // ZIP contents of containers folder @@ -269,18 +307,18 @@ function zipcontainers() { return gulp.src(paths.zipcontainers.src) .pipe(zip(paths.zipcontainers.zipfile)) .pipe(gulp.dest(paths.zipcontainers.dest)) - .pipe(notify({message: '<%= file.relative %> temporarily created!', title : 'zipcontainers', sound: false})); + .pipe(notify({message: '<%= file.relative %> temporarily created!', title : 'zipcontainers'})); } // ZIP everything else function zipelse() { return gulp.src(paths.zipelse.src, {base: '.'}) .pipe(gulp.dest(paths.zipelse.dest)) - .pipe(notify({message: '<%= file.relative %> temporarily created!', title : 'zipcontainers', sound: false})) + .pipe(notify({message: '<%= file.relative %> temporarily created!', title : 'zipcontainers'})) .pipe(replace('dist/', '')) .pipe(zip(paths.zipelse.zipfile)) .pipe(gulp.dest(paths.zipelse.dest)) - .pipe(notify({message: '<%= file.relative %> temporarily created!', title : 'zipcontainers', sound: false})); + .pipe(notify({message: '<%= file.relative %> temporarily created!', title : 'zipcontainers'})); } // git ziptemp @@ -291,14 +329,14 @@ function zippackage() { return gulp.src(paths.zippackage.src) .pipe(zip(paths.zippackage.zipfile)) .pipe(gulp.dest(paths.zippackage.dest)) - .pipe(notify({message: '<%= file.relative %> created!', title : 'zippackage', sound: false})); + .pipe(notify({message: '<%= file.relative %> created!', title : 'zippackage'})); } // Clean temp folder function cleantemp() { return gulp.src(paths.cleantemp.src) .pipe(clean()) - .pipe(notify({message: 'temp folder cleaned up!', title : 'cleantemp', sound: false})); + .pipe(notify({message: 'temp folder cleaned up!', title : 'cleantemp'})); } /*------------------------------------------------------*/ /* END PACKAGING TASKS ---------------------------------*/ @@ -327,8 +365,11 @@ function watch() { gulp.watch(paths.containers.src, containers); } +// gulp images +var images = gulp.series(optimize, convert); + // gulp init -var init = gulp.series(fontsInit, faFontsInit, faCssInit, slimMenuInit, normalizeInit, bsJsInit); +var init = gulp.series(fontsInit, faFontsInit, faCssInit, slimMenuInit, normalizeInit, bsJsInit, modernizrInit); // gulp build var build = gulp.series(cleandist, init, styles, scripts, images, containers, manifest); @@ -350,7 +391,10 @@ exports.faCssInit = faCssInit; exports.slimMenuInit = slimMenuInit; exports.normalizeInit = normalizeInit; exports.bsJsInit = bsJsInit; +exports.convert = convert; +exports.optimize = optimize; exports.images = images; +exports.modernizrInit = modernizrInit; exports.styles = styles; exports.scripts = scripts; exports.containers = containers; diff --git a/manifest.dnn b/manifest.dnn index 0b9c222..b2f3f74 100644 --- a/manifest.dnn +++ b/manifest.dnn @@ -1,6 +1,6 @@ - + nvQuickTheme A DNN Theme Dev Framework MyIcon.png @@ -80,6 +80,8 @@ + + diff --git a/menus/main/MainMenu.txt b/menus/main/MainMenu.txt index 5d9f098..6fa7c9d 100644 --- a/menus/main/MainMenu.txt +++ b/menus/main/MainMenu.txt @@ -6,9 +6,9 @@ [?ENABLED] - [=TEXT] + [=TEXT] [?ELSE] - [=TEXT] + [=TEXT] [/?] [?NODE] @@ -23,9 +23,9 @@
  • [?ENABLED] - [=TEXT] + [=TEXT] [?ELSE] - [=TEXT] + [=TEXT] [/?] [?NODE] @@ -34,4 +34,4 @@ [/?]
  • - [/>] \ No newline at end of file + [/>] diff --git a/menus/razor/RazorMenu.cshtml b/menus/razor/RazorMenu.cshtml index bd034b0..afd2acc 100644 --- a/menus/razor/RazorMenu.cshtml +++ b/menus/razor/RazorMenu.cshtml @@ -18,15 +18,16 @@ var hasChildren = page.HasChildren(); var split = hasChildren ? "split" : string.Empty; var single = hasChildren ? "single" :string.Empty; + var attrTarget = !string.IsNullOrEmpty(page.Target) ? ("target=\"" + page.Target + "\"") :string.Empty; -
  • +
  • @if (page.Enabled) { - @page.Text + @page.Text } else { - @page.Text + @page.Text } @if (hasChildren) @@ -45,15 +46,16 @@ { var hasChildren = page.HasChildren(); var split = hasChildren ? "split" : string.Empty; + var attrTarget = !string.IsNullOrEmpty(page.Target) ? ("target=\"" + page.Target + "\"") :string.Empty;
  • @if (page.Enabled) { - @page.Text + @page.Text } else { - @page.Text + @page.Text } @if (hasChildren) @@ -64,4 +66,4 @@ }
  • } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 349ecfe..5eeca8f 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,35 @@ { "name": "nvquicktheme", - "version": "2.2.1", + "version": "2.3.0", "description": "Barebones Bootstrap 4 DNN Theme", "main": "gulpfile.js", "author": "nvisionative", "license": "GPL-3.0", "private": true, "dependencies": { - "@fortawesome/fontawesome-free": "^5.13.1", - "bootstrap": "^4.4.1", + "@fortawesome/fontawesome-free": "^5.15.4", + "bootstrap": "^4.6.1", "normalize.css": "^8.0.1" }, "devDependencies": { - "browser-sync": "^2.26.7", + "browser-sync": "^2.27.9", "gulp": "^4.0.2", - "gulp-autoprefixer": "^6.0.0", + "gulp-autoprefixer": "^8.0.0", "gulp-clean": "^0.4.0", - "gulp-clean-css": "^4.0.0", - "gulp-imagemin": "^5.0.3", - "gulp-jshint": "2.x", - "gulp-notify": "^3.0.0", - "gulp-rename": "^1.2.2", - "gulp-replace": "^1.0.0", - "gulp-sass": "^4.0.2", - "gulp-uglify": "^3.0.0", - "gulp-zip": "^4.1.0", - "jshint": "^2.9.5" + "gulp-clean-css": "^4.3.0", + "gulp-imagemin": "^7.1.0", + "gulp-jshint": "^2.1.0", + "gulp-modernizr": "^4.0.3", + "gulp-notify": "^4.0.0", + "gulp-rename": "^2.0.0", + "gulp-replace": "^1.1.3", + "gulp-sass": "^5.1.0", + "gulp-uglify": "^3.0.2", + "gulp-webp": "^4.0.1", + "gulp-zip": "^5.1.0", + "imagemin-webp": "^6.0.0", + "jshint": "^2.13.4", + "sass": "^1.50.1" }, "browserslist": [ "> 1%", diff --git a/partials/_footer.ascx b/partials/_footer.ascx index c067468..2dc4af6 100644 --- a/partials/_footer.ascx +++ b/partials/_footer.ascx @@ -1,20 +1,28 @@ -
    -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    -
    -
    -
      -
    • -
    • -
    • -
    +
    +
    +
    +
    +
      +
    • +
    • +
    • +
    +
    +
    - - -
    \ No newline at end of file +
    + \ No newline at end of file diff --git a/partials/_header.ascx b/partials/_header.ascx index 0d619e5..d54c56d 100644 --- a/partials/_header.ascx +++ b/partials/_header.ascx @@ -1,8 +1,8 @@ -
    -
    +
    +
    -
    -
      +
      +
      • @@ -11,11 +11,11 @@
    -
    +
    -