Added support for Gulp for building
Signed-off-by: Jim Martens <github@2martens.de>
This commit is contained in:
@ -50,3 +50,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
<script type="text/javascript" src="/assets/js/main.js" defer></script>
|
||||||
|
<script>
|
||||||
|
echo.init({
|
||||||
|
offset: 500,
|
||||||
|
throttle: 250,
|
||||||
|
unload: false
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<noscript><link rel="stylesheet" href="/assets/css/main.css" type="text/css"></noscript>
|
||||||
|
|||||||
@ -29,8 +29,118 @@
|
|||||||
{% if author %}
|
{% if author %}
|
||||||
<meta property="article:author" content="{{ author.name }}" />
|
<meta property="article:author" content="{{ author.name }}" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% asset main.css %}
|
|
||||||
{% asset fa-svg-with-js.css %}
|
<link rel="preload" href="/assets/css/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||||
|
<script>
|
||||||
|
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
|
||||||
|
(function( w ){
|
||||||
|
"use strict";
|
||||||
|
// rel=preload support test
|
||||||
|
if( !w.loadCSS ){
|
||||||
|
w.loadCSS = function(){};
|
||||||
|
}
|
||||||
|
// define on the loadCSS obj
|
||||||
|
var rp = loadCSS.relpreload = {};
|
||||||
|
// rel=preload feature support test
|
||||||
|
// runs once and returns a function for compat purposes
|
||||||
|
rp.support = (function(){
|
||||||
|
var ret;
|
||||||
|
try {
|
||||||
|
ret = w.document.createElement( "link" ).relList.supports( "preload" );
|
||||||
|
} catch (e) {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
return function(){
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
// if preload isn't supported, get an asynchronous load by using a non-matching media attribute
|
||||||
|
// then change that media back to its intended value on load
|
||||||
|
rp.bindMediaToggle = function( link ){
|
||||||
|
// remember existing media attr for ultimate state, or default to 'all'
|
||||||
|
var finalMedia = link.media || "all";
|
||||||
|
|
||||||
|
function enableStylesheet(){
|
||||||
|
// unbind listeners
|
||||||
|
if( link.addEventListener ){
|
||||||
|
link.removeEventListener( "load", enableStylesheet );
|
||||||
|
} else if( link.attachEvent ){
|
||||||
|
link.detachEvent( "onload", enableStylesheet );
|
||||||
|
}
|
||||||
|
link.setAttribute( "onload", null );
|
||||||
|
link.media = finalMedia;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind load handlers to enable media
|
||||||
|
if( link.addEventListener ){
|
||||||
|
link.addEventListener( "load", enableStylesheet );
|
||||||
|
} else if( link.attachEvent ){
|
||||||
|
link.attachEvent( "onload", enableStylesheet );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set rel and non-applicable media type to start an async request
|
||||||
|
// note: timeout allows this to happen async to let rendering continue in IE
|
||||||
|
setTimeout(function(){
|
||||||
|
link.rel = "stylesheet";
|
||||||
|
link.media = "only x";
|
||||||
|
});
|
||||||
|
// also enable media after 3 seconds,
|
||||||
|
// which will catch very old browsers (android 2.x, old firefox) that don't support onload on link
|
||||||
|
setTimeout( enableStylesheet, 3000 );
|
||||||
|
};
|
||||||
|
|
||||||
|
// loop through link elements in DOM
|
||||||
|
rp.poly = function(){
|
||||||
|
// double check this to prevent external calls from running
|
||||||
|
if( rp.support() ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var links = w.document.getElementsByTagName( "link" );
|
||||||
|
for( var i = 0; i < links.length; i++ ){
|
||||||
|
var link = links[ i ];
|
||||||
|
// qualify links to those with rel=preload and as=style attrs
|
||||||
|
if( link.rel === "preload" && link.getAttribute( "as" ) === "style" && !link.getAttribute( "data-loadcss" ) ){
|
||||||
|
// prevent rerunning on link
|
||||||
|
link.setAttribute( "data-loadcss", true );
|
||||||
|
// bind listeners to toggle media back
|
||||||
|
rp.bindMediaToggle( link );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// if unsupported, run the polyfill
|
||||||
|
if( !rp.support() ){
|
||||||
|
// run once at least
|
||||||
|
rp.poly();
|
||||||
|
|
||||||
|
// rerun poly on an interval until onload
|
||||||
|
var run = w.setInterval( rp.poly, 500 );
|
||||||
|
if( w.addEventListener ){
|
||||||
|
w.addEventListener( "load", function(){
|
||||||
|
rp.poly();
|
||||||
|
w.clearInterval( run );
|
||||||
|
} );
|
||||||
|
} else if( w.attachEvent ){
|
||||||
|
w.attachEvent( "onload", function(){
|
||||||
|
rp.poly();
|
||||||
|
w.clearInterval( run );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// commonjs
|
||||||
|
if( typeof exports !== "undefined" ){
|
||||||
|
exports.loadCSS = loadCSS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
w.loadCSS = loadCSS;
|
||||||
|
}
|
||||||
|
}( typeof global !== "undefined" ? global : this ) );
|
||||||
|
</script>
|
||||||
|
<style>{% include critical.css %}</style>
|
||||||
|
|
||||||
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
|
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
|
||||||
<link rel="alternate" type="application/rss+xml" title="{{ site.title }}"
|
<link rel="alternate" type="application/rss+xml" title="{{ site.title }}"
|
||||||
href="{{ site.baseurl }}{% link feed.xml %}">
|
href="{{ site.baseurl }}{% link feed.xml %}">
|
||||||
@ -44,14 +154,4 @@
|
|||||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
|
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
|
||||||
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
|
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
|
||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"></script>
|
||||||
{% asset main.js %}
|
|
||||||
{% asset echo.js %}
|
|
||||||
<script defer>
|
|
||||||
echo.init({
|
|
||||||
offset: 500,
|
|
||||||
throttle: 250,
|
|
||||||
unload: false
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% asset fontawesome-all.js defer %}
|
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
249
gulpfile.js
Normal file
249
gulpfile.js
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Define variables.
|
||||||
|
const autoprefixer = require("autoprefixer");
|
||||||
|
const browserSync = require("browser-sync").create();
|
||||||
|
const cleancss = require("gulp-clean-css");
|
||||||
|
const concat = require("gulp-concat");
|
||||||
|
const del = require("del");
|
||||||
|
const gulp = require("gulp");
|
||||||
|
const gutil = require("gulp-util");
|
||||||
|
const imagemin = require("gulp-imagemin");
|
||||||
|
const notify = require("gulp-notify");
|
||||||
|
const postcss = require("gulp-postcss");
|
||||||
|
const rename = require("gulp-rename");
|
||||||
|
const run = require("gulp-run");
|
||||||
|
const runSequence = require("run-sequence");
|
||||||
|
const sass = require("gulp-ruby-sass");
|
||||||
|
const sprockets = require("gulp-sprockets");
|
||||||
|
const uglify = require("gulp-uglify");
|
||||||
|
|
||||||
|
// Include paths file.
|
||||||
|
const paths = require("./_assets/gulp_config/paths");
|
||||||
|
|
||||||
|
sprockets.declare(paths.sprocketsDirs, paths.siteJsFiles);
|
||||||
|
|
||||||
|
// Uses Sass compiler to process styles, adds vendor prefixes, minifies, then
|
||||||
|
// outputs file to the appropriate location.
|
||||||
|
gulp.task("build:styles:main", function() {
|
||||||
|
return sass(paths.sassFiles + "/main.scss", {
|
||||||
|
style: "compressed",
|
||||||
|
trace: true,
|
||||||
|
loadPath: [paths.sassFiles]
|
||||||
|
}).pipe(postcss([ autoprefixer({ browsers: ["last 2 versions"] }) ]))
|
||||||
|
.pipe(cleancss())
|
||||||
|
.pipe(gulp.dest(paths.jekyllCssFiles))
|
||||||
|
.pipe(gulp.dest(paths.siteCssFiles))
|
||||||
|
.pipe(browserSync.stream())
|
||||||
|
.on("error", gutil.log);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Processes critical CSS, to be included in head.html.
|
||||||
|
gulp.task("build:styles:critical", function() {
|
||||||
|
return sass(paths.sassFiles + "/critical.scss", {
|
||||||
|
style: "compressed",
|
||||||
|
trace: true,
|
||||||
|
loadPath: [paths.sassFiles]
|
||||||
|
}).pipe(postcss([ autoprefixer({ browsers: ["last 2 versions"] }) ]))
|
||||||
|
.pipe(cleancss())
|
||||||
|
.pipe(gulp.dest("_includes"))
|
||||||
|
.on("error", gutil.log);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Builds all styles.
|
||||||
|
gulp.task("build:styles", ["build:styles:main", "build:styles:critical"]);
|
||||||
|
|
||||||
|
gulp.task("clean:styles", function(callback) {
|
||||||
|
del([paths.jekyllCssFiles + "main.css",
|
||||||
|
paths.siteCssFiles + "main.css",
|
||||||
|
"_includes/critical.css"
|
||||||
|
]);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Concatenates and uglifies global JS files and outputs result to the
|
||||||
|
// appropriate location.
|
||||||
|
gulp.task("build:scripts:global", function() {
|
||||||
|
return gulp.src([
|
||||||
|
paths.jsFiles + "/global/lib" + paths.jsPattern,
|
||||||
|
paths.jsFiles + "/global/*.js"
|
||||||
|
])
|
||||||
|
.pipe(sprockets.js())
|
||||||
|
.pipe(concat("main.js"))
|
||||||
|
.pipe(uglify())
|
||||||
|
.pipe(gulp.dest(paths.jekyllJsFiles))
|
||||||
|
.pipe(gulp.dest(paths.siteJsFiles))
|
||||||
|
.on("error", gutil.log);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("clean:scripts", function(callback) {
|
||||||
|
del([paths.jekyllJsFiles + "main.js", paths.siteJsFiles + "main.js"]);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Concatenates and uglifies leaflet JS files and outputs result to the
|
||||||
|
// appropriate location.
|
||||||
|
gulp.task("build:scripts:leaflet", function() {
|
||||||
|
return gulp.src([
|
||||||
|
paths.jsFiles + "/leaflet/leaflet.js",
|
||||||
|
paths.jsFiles + "/leaflet/leaflet-providers.js"
|
||||||
|
])
|
||||||
|
.pipe(concat("leaflet.js"))
|
||||||
|
.pipe(uglify())
|
||||||
|
.pipe(gulp.dest(paths.jekyllJsFiles))
|
||||||
|
.pipe(gulp.dest(paths.siteJsFiles))
|
||||||
|
.on("error", gutil.log);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("clean:scripts:leaflet", function(callback) {
|
||||||
|
del([paths.jekyllJsFiles + "leaflet.js", paths.siteJsFiles + "leaflet.js"]);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Builds all scripts.
|
||||||
|
gulp.task("build:scripts", ["build:scripts:global", "build:scripts:leaflet"]);
|
||||||
|
|
||||||
|
// Optimizes and copies image files.
|
||||||
|
gulp.task("build:images", function() {
|
||||||
|
return gulp.src(paths.imageFilesGlob)
|
||||||
|
.pipe(imagemin())
|
||||||
|
.pipe(gulp.dest(paths.jekyllImageFiles))
|
||||||
|
.pipe(gulp.dest(paths.siteImageFiles))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("clean:images", function(callback) {
|
||||||
|
del([paths.jekyllImageFiles, paths.siteImageFiles]);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Runs jekyll build command.
|
||||||
|
gulp.task("build:jekyll", function() {
|
||||||
|
var shellCommand = "bundle exec jekyll build --config _config.yml";
|
||||||
|
|
||||||
|
return gulp.src("")
|
||||||
|
.pipe(run(shellCommand))
|
||||||
|
.on("error", gutil.log);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Runs jekyll build command using test config.
|
||||||
|
gulp.task("build:jekyll:test", function() {
|
||||||
|
var shellCommand = "bundle exec jekyll build --config _config.yml,_config.test.yml";
|
||||||
|
|
||||||
|
return gulp.src("")
|
||||||
|
.pipe(run(shellCommand))
|
||||||
|
.on("error", gutil.log);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Runs jekyll build command using local config.
|
||||||
|
gulp.task("build:jekyll:local", function() {
|
||||||
|
var shellCommand = "bundle exec jekyll build --config _config.yml,_config.test.yml,_config.dev.yml";
|
||||||
|
|
||||||
|
return gulp.src("")
|
||||||
|
.pipe(run(shellCommand))
|
||||||
|
.on("error", gutil.log);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Deletes the entire _site directory.
|
||||||
|
gulp.task("clean:jekyll", function(callback) {
|
||||||
|
del(["_site"]);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("clean", ["clean:jekyll",
|
||||||
|
"clean:images",
|
||||||
|
"clean:scripts",
|
||||||
|
"clean:styles"]);
|
||||||
|
|
||||||
|
// Builds site anew.
|
||||||
|
gulp.task("build", function(callback) {
|
||||||
|
runSequence("clean",
|
||||||
|
["build:scripts", "build:images", "build:styles"],
|
||||||
|
"build:jekyll",
|
||||||
|
callback);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Builds site anew using test config.
|
||||||
|
gulp.task("build:test", function(callback) {
|
||||||
|
runSequence("clean",
|
||||||
|
["build:scripts", "build:images", "build:styles"],
|
||||||
|
"build:jekyll:test",
|
||||||
|
callback);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Builds site anew using local config.
|
||||||
|
gulp.task("build:local", function(callback) {
|
||||||
|
runSequence("clean",
|
||||||
|
["build:scripts", "build:images", "build:styles"],
|
||||||
|
"build:jekyll:local",
|
||||||
|
callback);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Default Task: builds site.
|
||||||
|
gulp.task("default", ["build"]);
|
||||||
|
|
||||||
|
// Special tasks for building and then reloading BrowserSync.
|
||||||
|
gulp.task("build:jekyll:watch", ["build:jekyll:local"], function(callback) {
|
||||||
|
browserSync.reload();
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("build:scripts:watch", ["build:scripts"], function(callback) {
|
||||||
|
browserSync.reload();
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Static Server + watching files.
|
||||||
|
// Note: passing anything besides hard-coded literal paths with globs doesn't
|
||||||
|
// seem to work with gulp.watch().
|
||||||
|
gulp.task("serve", ["build:local"], function() {
|
||||||
|
|
||||||
|
browserSync.init({
|
||||||
|
server: paths.siteDir,
|
||||||
|
ghostMode: false, // Toggle to mirror clicks, reloads etc. (performance)
|
||||||
|
logFileChanges: true,
|
||||||
|
logLevel: "debug",
|
||||||
|
open: true // Toggle to automatically open page when starting.
|
||||||
|
});
|
||||||
|
|
||||||
|
// Watch site settings.
|
||||||
|
gulp.watch(["_config.yml"], ["build:jekyll:watch"]);
|
||||||
|
|
||||||
|
// Watch .scss files; changes are piped to browserSync.
|
||||||
|
gulp.watch("_assets/styles/**/*.scss", ["build:styles"]);
|
||||||
|
|
||||||
|
// Watch .js files.
|
||||||
|
gulp.watch("_assets/js/**/*.js", ["build:scripts:watch"]);
|
||||||
|
|
||||||
|
// Watch image files; changes are piped to browserSync.
|
||||||
|
gulp.watch("_assets/img/**/*", ["build:images"]);
|
||||||
|
|
||||||
|
// Watch posts.
|
||||||
|
gulp.watch("_posts/**/*.+(md|markdown|MD)", ["build:jekyll:watch"]);
|
||||||
|
|
||||||
|
// Watch drafts if --drafts flag was passed.
|
||||||
|
if (module.exports.drafts) {
|
||||||
|
gulp.watch("_drafts/*.+(md|markdown|MD)", ["build:jekyll:watch"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch html and markdown files.
|
||||||
|
gulp.watch(["**/*.+(html|md|markdown|MD)", "!_site/**/*.*"], ["build:jekyll:watch"]);
|
||||||
|
|
||||||
|
// Watch RSS feed XML files.
|
||||||
|
gulp.watch("**.xml", ["build:jekyll:watch"]);
|
||||||
|
|
||||||
|
// Watch data files.
|
||||||
|
gulp.watch("_data/**.*+(yml|yaml|csv|json)", ["build:jekyll:watch"]);
|
||||||
|
|
||||||
|
// Watch favicon.png.
|
||||||
|
gulp.watch("favicon.png", ["build:jekyll:watch"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Updates Ruby gems
|
||||||
|
gulp.task("update:bundle", function() {
|
||||||
|
return gulp.src("")
|
||||||
|
.pipe(run("bundle install"))
|
||||||
|
.pipe(run("bundle update"))
|
||||||
|
.pipe(notify({ message: "Bundle Update Complete" }))
|
||||||
|
.on("error", gutil.log);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user