Sage-Roots
Setup
Refer to the roots.io official documentation for instructions to setup and check back for future updates.
- The above will require a working machine setup with composer installed, node and yarn.
- Update the theme file
composer.json
with any further PHP dependencies thenrun composer update
- Update
package.json
with any further Node dependencies and run npm install if node_modules exists ornpm update
otherwise
yarn
Refer to the the package.json file for tasks to run. Use yarn run
rather than npm run
to maintain consistency in handling the dependencies and their versions.
Converting project from older versions of Roots
- Install a new theme then switch to it in the WordPress admin
- Look through existing PHP templates and rename with the
.blade.php
suffix - Check to make sure the relative paths correspond to your local directory in the config file so that files are compiled in the correct place
-
{your-new-roots-theme}/resources/assets/config.json
-
- Replace references to get templates with
@include
- Check any included partials and templates within pages and use the
@include
syntax as a replacement - For page conditional statements used to display entire page templates located in theme root, replace these with the syntax for example:
if: ( is_page_template('views/template-example.php')
and move the page templates to the corresponding folder in views. Check all the pages in WordPress which use a non-default template as it's likely you will need to reassign the template within the WordPress admin and save. - Also check the content within pages as the formatting may need to be restored with the original headings, paragraphs, etc.
- Replace any content loops and if statements with the syntax used in Laravel if content isn't display. It may also be necessary to resave the page in the WordPress admin to trigger it to use the latest template changes.
- Likely running
yarn start
oryarn build
will result in errors the first time. Check what code is causing compile errors as some older projects may have a lot. Disable linting in some cases where there are a lot of errors:- For JavaScript errors go to the file and surround the code with disable/enable flags, e.g. in
{your-new-roots-theme}/resources/assets/scripts/routes/common.js
add/*eslint-disable */
and/*eslint-enable */
- For sass/scss disable the linting manually in the config
{your-new-roots-theme}/resources/assets/build/webpack.config.js
comment out the block forStyleLintPlugin
- For JavaScript errors go to the file and surround the code with disable/enable flags, e.g. in
Converting older Grunt to Gulp task manager setup
Some of the original Sage-Roots themes we built during 2013-2015 used Grunt task manager and have consequently changed a lot since then with newer dependencies and plugins. Convert from Grunt to Gulp with the following steps.
- Cancel any running tasks
- Remove
Gruntfile.js
andnode_modules
- Update
package.json
with the following as an example (newer dependency versions maybe available, if so then update these accordingly)
{
"name": "sage",
"version": "8.5.2",
"author": "Ben Word <ben@benword.com>",
"homepage": "https://roots.io/sage/",
"private": true,
"repository": {
"type": "git",
"url": "git://github.com/roots/sage.git"
},
"bugs": {
"url": "https://github.com/roots/sage/issues"
},
"licenses": [
{
"type": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
],
"scripts": {
"build": "bower install && gulp",
"jshint": "gulp jshint",
"jscs": "jscs gulpfile.js assets/scripts/*.js"
},
"engines": {
"node": ">= 4.5"
},
"devDependencies": {
"asset-builder": "^1.1.0",
"browser-sync": "^2.24.4",
"del": "^2.2.2",
"gulp": "^3.9.0",
"gulp-autoprefixer": "^3.1.1",
"gulp-changed": "^1.3.0",
"gulp-concat": "^2.6.0",
"gulp-cssnano": "^2.1.3",
"gulp-flatten": "0.3.1",
"gulp-if": "^2.0.1",
"gulp-imagemin": "^3.4.0",
"gulp-jshint": "^2.1.0",
"gulp-less": "^3.5.0",
"gulp-plumber": "^1.2.0",
"gulp-rename": "^1.2.3",
"gulp-rev": "^7.1.2",
"gulp-sass": "^2.0.1",
"gulp-sourcemaps": "^1.12.1",
"gulp-uglify": "^2.0.0",
"imagemin-pngcrush": "^5.0.0",
"jshint": "^2.9.7",
"jshint-stylish": "^2.0.1",
"lazypipe": "^1.0.1",
"merge-stream": "^1.0.0",
"minimist": "^1.1.3",
"run-sequence": "^1.1.2",
"traverse": "^0.6.6",
"wiredep": "^4.0.0"
},
"dependencies": {
"npm": "^5.10.0",
"short-and-sweet": "^1.0.2"
}
}
- Add
gulpfile.js
into the active theme folder with the following content. This example doesn't include jshint rules enabled in case you have many older plugins with Javascript that won't compile:
// ## Globals
var argv = require('minimist')(process.argv.slice(2));
var autoprefixer = require('gulp-autoprefixer');
var browserSync = require('browser-sync').create();
var changed = require('gulp-changed');
var concat = require('gulp-concat');
var flatten = require('gulp-flatten');
var gulp = require('gulp');
var gulpif = require('gulp-if');
var imagemin = require('gulp-imagemin');
var jshint = require('gulp-jshint');
var lazypipe = require('lazypipe');
var less = require('gulp-less');
var merge = require('merge-stream');
var cssNano = require('gulp-cssnano');
var plumber = require('gulp-plumber');
var rev = require('gulp-rev');
var runSequence = require('run-sequence');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
// See https://github.com/austinpray/asset-builder
var manifest = require('asset-builder')('./assets/manifest.json');
// `path` - Paths to base asset directories. With trailing slashes.
// - `path.source` - Path to the source files. Default: `assets/`
// - `path.dist` - Path to the build directory. Default: `dist/`
var path = manifest.paths;
// `config` - Store arbitrary configuration values here.
var config = manifest.config || {};
// `globs` - These ultimately end up in their respective `gulp.src`.
// - `globs.js` - Array of asset-builder JS dependency objects. Example:
// ```
// {type: 'js', name: 'main.js', globs: []}
// ```
// - `globs.css` - Array of asset-builder CSS dependency objects. Example:
// ```
// {type: 'css', name: 'main.css', globs: []}
// ```
// - `globs.fonts` - Array of font path globs.
// - `globs.images` - Array of image path globs.
// - `globs.bower` - Array of all the main Bower files.
var globs = manifest.globs;
// `project` - paths to first-party assets.
// - `project.js` - Array of first-party JS assets.
// - `project.css` - Array of first-party CSS assets.
var project = manifest.getProjectGlobs();
// CLI options
var enabled = {
// Enable static asset revisioning when `--production`
rev: argv.production,
// Disable source maps when `--production`
maps: !argv.production,
// Fail styles task on error when `--production`
failStyleTask: argv.production,
// Fail due to JSHint warnings only when `--production`
failJSHint: argv.production,
// Strip debug statments from javascript when `--production`
stripJSDebug: argv.production
};
// Path to the compiled assets manifest in the dist directory
var revManifest = path.dist + 'assets.json';
// Error checking; produce an error rather than crashing.
var onError = function(err) {
console.log(err.toString());
this.emit('end');
};
// ## Reusable Pipelines
// See https://github.com/OverZealous/lazypipe
// ### CSS processing pipeline
// Example
// ```
// gulp.src(cssFiles)
// .pipe(cssTasks('main.css')
// .pipe(gulp.dest(path.dist + 'styles'))
// ```
var cssTasks = function(filename) {
return lazypipe()
.pipe(function() {
return gulpif(!enabled.failStyleTask, plumber());
})
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.init());
})
.pipe(function() {
return gulpif('*.less', less());
})
.pipe(function() {
return gulpif('*.scss', sass({
outputStyle: 'nested', // libsass doesn't support expanded yet
precision: 10,
includePaths: ['.'],
errLogToConsole: !enabled.failStyleTask
}));
})
.pipe(concat, filename)
.pipe(autoprefixer, {
browsers: [
'last 2 versions',
'android 4',
'opera 12'
]
})
.pipe(cssNano, {
safe: true
})
.pipe(function() {
return gulpif(enabled.rev, rev());
})
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.write('.', {
sourceRoot: 'assets/styles/'
}));
})();
};
// ### JS processing pipeline
// Example
// ```
// gulp.src(jsFiles)
// .pipe(jsTasks('main.js')
// .pipe(gulp.dest(path.dist + 'scripts'))
// ```
var jsTasks = function(filename) {
return lazypipe()
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.init());
})
.pipe(concat, filename)
.pipe(uglify, {
compress: {
'drop_debugger': enabled.stripJSDebug
}
})
.pipe(function() {
return gulpif(enabled.rev, rev());
})
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.write('.', {
sourceRoot: 'assets/scripts/'
}));
})();
};
// ### Write to rev manifest
// If there are any revved files then write them to the rev manifest.
// See https://github.com/sindresorhus/gulp-rev
var writeToManifest = function(directory) {
return lazypipe()
.pipe(gulp.dest, path.dist + directory)
.pipe(browserSync.stream, {match: '**/*.{js,css}'})
.pipe(rev.manifest, revManifest, {
base: path.dist,
merge: true
})
.pipe(gulp.dest, path.dist)();
};
// ## Gulp tasks
// Run `gulp -T` for a task summary
// ### Styles
// `gulp styles` - Compiles, combines, and optimizes Bower CSS and project CSS.
// By default this task will only log a warning if a precompiler error is
// raised. If the `--production` flag is set: this task will fail outright.
gulp.task('styles', ['wiredep'], function() {
var merged = merge();
manifest.forEachDependency('css', function(dep) {
var cssTasksInstance = cssTasks(dep.name);
if (!enabled.failStyleTask) {
cssTasksInstance.on('error', function(err) {
console.error(err.message);
this.emit('end');
});
}
merged.add(gulp.src(dep.globs, {base: 'styles'})
.pipe(plumber({errorHandler: onError}))
.pipe(cssTasksInstance));
});
return merged
.pipe(writeToManifest('styles'));
});
// ### Scripts
// `gulp scripts` - Runs JSHint then compiles, combines, and optimizes Bower JS
// and project JS.
gulp.task('scripts', function() {
var merged = merge();
manifest.forEachDependency('js', function(dep) {
merged.add(
gulp.src(dep.globs, {base: 'scripts'})
.pipe(plumber({errorHandler: onError}))
.pipe(jsTasks(dep.name))
);
});
return merged
.pipe(writeToManifest('scripts'));
});
// ### Fonts
// `gulp fonts` - Grabs all the fonts and outputs them in a flattened directory
// structure. See: https://github.com/armed/gulp-flatten
gulp.task('fonts', function() {
return gulp.src(globs.fonts)
.pipe(flatten())
.pipe(gulp.dest(path.dist + 'fonts'))
.pipe(browserSync.stream());
});
// ### Images
// `gulp images` - Run lossless compression on all the images.
gulp.task('images', function() {
return gulp.src(globs.images)
.pipe(imagemin([
imagemin.jpegtran({progressive: true}),
imagemin.gifsicle({interlaced: true}),
imagemin.svgo({plugins: [
{removeUnknownsAndDefaults: false},
{cleanupIDs: false}
]})
]))
.pipe(gulp.dest(path.dist + 'images'))
.pipe(browserSync.stream());
});
// ### JSHint
// `gulp jshint` - Lints configuration JSON and project JS.
gulp.task('jshint', function() {
return gulp.src([
'bower.json', 'gulpfile.js'
].concat(project.js))
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'))
.pipe(gulpif(enabled.failJSHint, jshint.reporter('fail')));
});
// ### Clean
// `gulp clean` - Deletes the build folder entirely.
gulp.task('clean', require('del').bind(null, [path.dist]));
// ### Watch
// `gulp watch` - Use BrowserSync to proxy your dev server and synchronize code
// changes across devices. Specify the hostname of your dev server at
// `manifest.config.devUrl`. When a modification is made to an asset, run the
// build step for that asset and inject the changes into the page.
// See: http://www.browsersync.io
gulp.task('watch', function() {
browserSync.init({
files: ['{lib,templates}/**/*.php', '*.php'],
proxy: config.devUrl,
snippetOptions: {
whitelist: ['/wp-admin/admin-ajax.php'],
blacklist: ['/wp-admin/**']
}
});
gulp.watch([path.source + 'styles/**/*'], ['styles']);
gulp.watch([path.source + 'scripts/**/*'], ['scripts']);
gulp.watch([path.source + 'fonts/**/*'], ['fonts']);
gulp.watch([path.source + 'images/**/*'], ['images']);
gulp.watch(['bower.json', 'assets/manifest.json'], ['build']);
});
// ### Build
// `gulp build` - Run all the build tasks but don't clean up beforehand.
// Generally you should be running `gulp` instead of `gulp build`.
gulp.task('build', function(callback) {
runSequence('styles',
'scripts',
['fonts', 'images'],
callback);
});
// ### Wiredep
// `gulp wiredep` - Automatically inject Less and Sass Bower dependencies. See
// https://github.com/taptapship/wiredep
gulp.task('wiredep', function() {
var wiredep = require('wiredep').stream;
return gulp.src(project.css)
.pipe(wiredep())
.pipe(changed(path.source + 'styles', {
hasChanged: changed.compareSha1Digest
}))
.pipe(gulp.dest(path.source + 'styles'));
});
// ### Gulp
// `gulp` - Run a complete build. To compile for production run `gulp --production`.
gulp.task('default', ['clean'], function() {
gulp.start('build');
});
- Add
.bowerrc
(invisible) file with the following content:
{
"directory": "bower_components",
"registry": "https://registry.bower.io"
}
Add bower.json
file with the following content:
{
"name": "sage",
"homepage": "https://roots.io/sage/",
"authors": [
"Ben Word <ben@benword.com>"
],
"license": "MIT",
"private": true,
"dependencies": {
"slick": "git://github.com/kenwheeler/slick.git"
}
}
Create some new folders if they doesn't already exist for the assets and move existing CSS, Javascript and fonts to these. Remove any leftover compiled files with the same name as Scss files in the same folder:
-
wp-content/themes/{{active-theme}}/assets/styles
-
wp-content/themes/{{active-theme}}/assets/scripts
-
wp-content/themes/{{active-theme}}/assets/fonts
Inside of wp-content/themes/{{active-theme}}/assets/
add the file manifest.json
. Then add the following content plus any plugins (that aren't already included as dependencies above) in the list above scripts/main.js
. Also update the devUrl
for the browsersync feature to work when developing:
{
"dependencies": {
"main.js": {
"files": [
"scripts/main.js"
],
"main": true
},
"main.css": {
"files": [
"styles/main.scss"
],
"main": true
},
"customizer.js": {
"files": [
"scripts/customizer.js"
]
},
"jquery.js": {
"bower": ["jquery"]
}
},
"config": {
"devUrl": "http://{{your-localhost-domain}}"
}
}
Run npm install
and bower install
to setup dependencies for running Gulp.
Update wp-content/themes/{{active-theme}}/lib/scripts.php
so any assets point to the folder dist
e.g. get_template_directory_uri() . '/dist/styles/main.css'
. Also check any other templates where assets are loaded for this. Check the .htaccess
file as well for paths to add.
Finally run gulp watch
to run the task manager which will compile assets into dist
and run a localhost instance of the site.
Woocommerce
The theme does not inherently work fully with the Woocommerce plugin but there is a fix using WooCommerce integration for Sage 9 themes package which can be installed via composer. Follow the instructions fully on the readme for how to setup the templates for this.