- Update: 4-12-2018
For older versions of Sage see this post
Changes in Sage 9
- Laravel’s Blade as a templating engine.
Learn about Blade. Check out the templates directory.You can opt-out of Blade templates by replacing them with regular PHP ones (you could copy over the templates from Sage 8 if you really wanted to).
- Replaced gulp and Bower with Webpack and npm.
Bower is dead and all packages should be available on npm.Webpack is responsible for:
- ES6 for Javascript
Great resource for learning about ES6: Wes Bos’ ES6 for Everyone
Convert existing JS to ES6 with Lebab - Bootstrap 4
It’s still in alpha, but there’s so many improvements over Bootstrap 3. - PSR-2 coding standards.
Roots projects switched to PSR-2 last year. Previously we had used a modified PSR-2 ruleset, but we stopped caring about 2-spaces in our PHP files and fully adopted PSR-2. - Restructured theme files.
All theme templates are finally out of the theme root! Our implementation is a little hacky because a 7 year old WordPress Trac ticket still hasn’t landed, but we believe our implementation is the best we can do at this time. - Introduced Yarn.
Yarn is a drop in npm client replacement. With Yarn, the installation of Node dependencies is quicker & thenode_modules
directory is smaller.
Theme Installation
- Make sure all dependencies have been installed before moving on:
PHP >=5.6.47.1.3 (with php-mbstring enabled)
– Add the wamp php (at least 7.1.3) to Windows PATH (and no other php in the path).
– make sure extension=php_mbstring.dll is enabled in the php.ini of the php version you are using (default= enabled)
Composer (Dependency manager)
Node.js >= 6.9.x
– If necessary install Node (with npm). I used the Windows installer here (x64 version)
Yarn - From your WordPress themes directory, run the following composer command:
composer create-project roots/sage your-theme-name dev-master
During theme installation you will have the options to:
– Update theme headers (theme name, description, author, etc.)
– Select a CSS framework (Bootstrap, Foundation, none)
– Add Font AwesomeUpdate: Newest version of Sage9 (9.0.5 at the time of writing) gives the following error:
TTY mode is not supported on Windows platform
Solution: run this from the theme directory
./vendor/bin/sage meta # or edit style.css directly ./vendor/bin/sage config # or edit resources/assets/config.json ./vendor/bin/sage preset # Install css framework
- Navigate to the theme directory then run yarn, and yarn build (to refresh files):
yarn && yarn build
You now have all the necessary dependencies to run the build process.
About dependencies:
If you openpackage.json
you’ll see bothdevDependencies
anddependencies
that Sage uses.devDependencies
are used by the build process, whereasdependencies
are packages that are used in the front-end theme assets.dependencies
includes the front-end options you selected during install, such as Bootstrap and Font Awesome"dependencies": {
"bootstrap": "^4.0.0-beta",
"font-awesome": "~4.7",
"jquery": "1.12.4 - 3",
"popper.js": "~1.11"
}
————————–
Install WordPress and activate plugins
Optionally import test data with WP Test. See here
Warning when activating i-themes Security:
When activiating this plugin, it will write to your wp-config.php.
This causes an error with the Bedrock config setup and make you website/admin unaccesible.
Solution:
– activate i-themes
– edit wp-config.php -> remove file permissions added by i-themes (we use config/application.php for that)
– WP admin should be accesible again
– Go to i-themes settings-> WordPress Tweaks -> File Editor -> uncheck the box
- Test by running one of the build commands:
-
Build commands
yarn start
— Compile assets when file changes are made, start Browsersync sessionyarn build
— Compile and optimize the files in your assets directoryyarn build:production
— Compile assets for production
-
Additional commands
yarn run rmdist
— Remove yourdist/
folderyarn run lint
— Run ESLint against your assets and build scriptscomposer test
— Check your PHP for PSR-2 compliance withphpcs
- To use BrowserSync you need to update devUrl at the bottom of assets/config.json to reflect your local development hostname.If your local development URL is
https://project-name.dev
, update the file to read:"devUrl": "https://project-name.dev",
- If you are not using Bedrock, update publicPath to reflect your folder structure:
"publicPath": "/wp-content/themes/sage/"
- Problem: no update after blade template changes. Fixed thanks to this comment:
- Problem: Console connection error after manual page reload/change. Also the page is switching quickly between unstyled and styled for a few seconds.
The connection to http://localhost:3000/__webpack_hmr was interrupted while the page was loading.
Installing a newer version of Node (10.x instead of 6.9) and subsequently node-sass seems to have made the problem far less worse. The unstyled page is only visible for a short moment now. Connection to webpack is still lost, but that might be expected behaviour - update: not sure if the text below is relevant anymore.
By default, Browsersync will use webpack’s HMR, which won’t trigger a page reload in your browser.If you would like to force Browsersync to reload the page whenever certain file types are edited, then add them towatch
inassets/config.json
.... "watch": [ "assets/scripts/**/*.js", "templates/**/*.php", "src/**/*.php" ], ...
Customize Bootstrap
Strip out Bootstrap scss:
- Open theme/node_modules/bootstrap/scss/bootstrap.scss
- Grab all the imports and paste them into main.scss in the theme, while commenting out the main Bootstrap import
- Search and replace @import “ with @import “~bootstrap/scss/ on the Bootstrap imports only
- Comment out/delete those lines you don’t need
quote: Reduced my compiled CSS from 195K to 142K.
Example, if you only want a reset and the grid:
// Import npm dependencies
@import "~bootstrap/scss/bootstrap-reboot";
@import "~bootstrap/scss/bootstrap-grid";
BS4 JS
scripts/autoload/_bootstrap.js
imports all bootstrap with all functionalities at that location in main.scss
.
To remove all Bootstrap 4 JS remove this line in main.js:
// Import everything from autoload
import './autoload/**/*'
loading individual components:
// Required
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
// Optional
@import "~bootstrap/scss/root";
@import "~bootstrap/scss/reboot";
@import "~bootstrap/scss/type";
@import "~bootstrap/scss/images";
@import "~bootstrap/scss/code";
@import "~bootstrap/scss/grid";
// @import "~bootstrap/scss/tables";
@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/buttons";
// @import "~bootstrap/scss/transitions";
// @import "~bootstrap/scss/dropdown";
// @import "~bootstrap/scss/button-group";
// @import "~bootstrap/scss/input-group";
// @import "~bootstrap/scss/custom-forms";
@import "~bootstrap/scss/nav";
@import "~bootstrap/scss/navbar";
// @import "~bootstrap/scss/card";
// @import "~bootstrap/scss/breadcrumb";
// @import "~bootstrap/scss/pagination";
// @import "~bootstrap/scss/badge";
// @import "~bootstrap/scss/jumbotron";
// @import "~bootstrap/scss/alert";
// @import "~bootstrap/scss/progress";
// @import "~bootstrap/scss/media";
// @import "~bootstrap/scss/list-group";
@import "~bootstrap/scss/close";
@import "~bootstrap/scss/modal";
// @import "~bootstrap/scss/tooltip";
// @import "~bootstrap/scss/popover";
// @import "~bootstrap/scss/carousel";
@import "~bootstrap/scss/utilities";
// @import "~bootstrap/scss/print";
Documentation
Editor Setup
Recommende packages for Sublime/ Atom etc:
- Editorconfig -> Sage and the other Roots projects use the .editorconfig file to help enforce spacing consistency.
(EditorConfig plugins look for a file named .editorconfig in the directory of the opened file and in every parent directory). - Emmet – Improves HTML & CSS workflow
- highlight-selected – Higlight current selected word everywhere it appears in the file (not a Sublime package)
- language-blade (not a Sublime package) -> use Laravel Blade Highlighter instead
Coding standards:
- Sage uses 4 spaces for PHP files, with the exception of template files, as it follows the PSR-2 coding standards.
- Two spaces are used for everything else, including Sass, JavaScript, and JSON.
- Mark Otto, the creator of Bootstrap, has a well-documented code guide for front-end developers at http://codeguide.co/ . Some examples:
- Avoid superfluous parent elements when writing HTML
- Keep classes lowercase and use dashes for class names
- Keep classes as short and succinct as possible
- Use meaningful names; use structural or purposeful names over presentational
- Prefix classes based on the closest parent or base class
- Use soft-tabs set to two spaces
- Avoid unnecessary nesting
Javascript E6
- Sage uses ES6 for the JavaScript that’s included in the theme. Since Sage strives to use the current best practices for
modern front-end development, the theme allows the usage of ES6 and also enforces coding standards with ESLint. - The ESLint configuration is located at
assets/build/.eslintrc
, where you might want to make changes that fit your own
coding styles. - We’ve picked Airbnb’s JavaScript standard as the basis for ours.
- To disable the linting in a specific file or within a file, use inline comments:
/* eslint-disable */
alert('foo');
/* eslint-enable */
- I had to add this file to the project root to remove eslint warnings
.jshintrc
{
'eslintversion': 6
}
Theme Configuration and Setup
app/setup.php
is used to enqueue stylesheets and scripts, register support for theme features with add_theme_support
, and register navigation menus and sidebars.
NOTE: If you see Jquery not found errors in the console (I had this problem with gravity forms), you might want to disable the line with
add_theme_support('soil-jquery-cdn');
jQuery will then be put in the head and load before other plugins. A better solution is probable to properly enqueue the plugin assets?
NOTE: If you don’t use Bedrock as your WordPress stack, you’ll want to add the following to your wp-config.php on your development installation:
define(‘WP_ENV’, ‘development’);Note: If WP_ENV is not defined WP_ENV will be set to production, which may be just what you want. See other post
Stylesheets and scripts
Manage your front-end theme assets from the app/setup.php
file:
add_action('wp_enqueue_scripts', function () { wp_enqueue_style('sage/main.css', asset_path('styles/main.css'), false, null); wp_enqueue_script('sage/main.js', asset_path('scripts/main.js'), ['jquery'], null, true); }, 100);
See theme assets for more on how these assets are built.asset_path
is a helper function that returns versioned asset filenames from thedist/
directory.
Theme features
Soil
We recommend using the Soil Plugin with every WordPress install for additional features:
- Load jQuery from the jQuery CDN*
- Cleaner WordPress markup*
- Cleaner HTML output of navigation menus*
- Root relative URLs*
- Nice search*
- Google Analytics snippet from HTML5 Boilerplate
- Move all JS to the footer
- Disable trackbacks and pingbacks
∗If Soil is installed and activated on your WordPress install, Sage will enable these features by default.
Title tag support
add_theme_support('title-tag')
is a feature added in WordPress 4.1 that allows themes and plugins to manage the document title. This means that there’s no <title>
tag found in the head template since it’s automatically added by wp_head()
.
Sage registers a navigation menu called Primary Navigation. Additional menus should be added in the register_nav_menus
locations array.
Post thumbnails
Post thumbnails are enabled with add_theme_support('post-thumbnails')
, but they aren’t output on any of the default templates. Add custom post thumbnail sizes with add_image_size()
.
HTML5 markup
Sage enables HTML5 markup for captions, comment forms, comment lists, galleries, and the search form.
Editor stylesheet
The TinyMCE editor in WordPress allows loading a custom stylesheet which is registered with add_editor_style()
. The editor stylesheet is automatically generated from your main theme stylesheet when you run the build script.
Sage registers two sidebars by default: Primary & Footer. Add additional sidebars with register_sidebar()
.
Theme structure
themes/your-theme-name/ # → Root of your Sage based theme
├── app/ # → Theme PHP
│ ├── controllers/ # → Controller files
│ ├── admin.php # → Theme customizer setup
│ ├── filters.php # → Theme filters
│ ├── helpers.php # → Helper functions
│ └── setup.php # → Theme setup
├── config/ # → Theme configuration
├── composer.json # → Autoloading for `app/` files
├── composer.lock # → Composer lock file (never edit)
├── dist/ # → Built theme assets (never edit)
├── node_modules/ # → Node.js packages (never edit)
├── package.json # → Node.js dependencies and scripts
├── resources/ # → Theme assets and templates
│ ├── assets/ # → Front-end assets
│ │ ├── config.json # → Settings for compiled assets
│ │ ├── build/ # → Webpack and ESLint config
│ │ ├── fonts/ # → Theme fonts
│ │ ├── images/ # → Theme images
│ │ ├── scripts/ # → Theme JS
│ │ └── styles/ # → Theme stylesheets
│ ├── functions.php # → Composer autoloader, theme includes
│ ├── index.php # → Never manually edit
│ ├── screenshot.png # → Theme screenshot for WP admin
│ ├── style.css # → Theme meta information
│ └── views/ # → Theme templates
│ ├── layouts/ # → Base templates
│ └── partials/ # → Partial templates
└── vendor/ # → Composer packages (never edit)
Customizing templates
The resources/views/
directory contains files that you can further extend with the normal WordPress Template Hierarchy
Here’s what’s happening with these hooks:
- WordPress detects theme in
themes/sage/resources
- When we activate, we tell WordPress that the theme is actually in
themes/sage/resources/views
- When we call
get_template_directory()
orget_template_directory_uri()
, we point it back tothemes/sage/resources
We do this so that the Template Hierarchy will look in themes/sage/resources/views
for core WordPress themes, but functions.php
, style.css
, and index.php
are all still located in themes/sage/resources
.
This is not compatible with the WordPress Customizer theme preview prior to theme activation
Note that functions.php
, screenshot.png
and style.css
exist in the resources/ directory
and not the theme root. This does currently come with some tradeoffs. sage-installer Issue #3 is tracking an option to move the required theme files back to the theme root folder. You’ll need to follow the instructions from dmgawel if allowing your theme to be uploaded via zip to the WordPress admin is a requirement.
Blade Templates
Sage uses Laravel’s Blade templating engine. Some of the benefits that come with using a templating engine include:
- Template inheritance In previous versions of Sage we accomplished template inheritance with the theme wrapper.
- Separation of data from views Pass your logic to template files instead of including PHP in your views files
- Automatically escaped data When you include data with Blade, such as with
{{ get_post_meta(get_the_ID(), 'example', true) }}
(or{{ get_field('example') }}
if you use ACF), the data is automatically escaped.
This means that you don’t need to useesc_url
or other sanitizing functions in WordPress when outputting data in templates. - Beautiful looking code The Blade syntax is pretty clean!
Template inheritance
One of the biggest benefits of using Blade templates is the ability to remove any repeated markup from individual templates and put it into a single file. This file, resources/views/layouts/app.blade.ph
p, becomes the base layout file. By doing this we can put the focus entirely on the page specific markup and loop, simplifying our templates.
Passing data to templates
Sage includes a sage/template/{$class}/data
filter that can be used to pass data to templates. This is the most simple way to pass data. The filter is based of body classes and can be used to target specific templates, for example:
sage/template/home/data
— Home pagesage/template/about/data
— About pagesage/template/page/data
— All pagessage/template/post-type-archive-event/data
— event post type archivesage/template/single-event/data
— event single post template
Note: Sage comes ready for you to modify the body_class
by editing the filter at the top of app/filters.php
.
In the example below we’re passing the the values of two ACF fields, header_image
and header_content
, to all pages:
add_filter('sage/template/page/data', function (array $data) {
$data['header_image'] = get_field('header_image');
$data['header_content'] = get_field('header_content');
return $data;
});
In your Blade templates for pages you can now use {{ $header_image }}
and {{ $header_content }}
to output the data.
404.blade.php
- Error 404 page
index.blade.php
- Archive page (used by blog page, category archives, author archives and more)
page.blade.php
- Single page
search.blade.php
- Search results page
single.blade.php
- Single post page
template-custom.blade.php
- An example single page template
All templates are wrapped by a base file in the layouts/
directory:
app.blade.php
- The base template which wraps the base markup around all template files
These files include templates from the resources/views/partials/
directory which is where you’ll be making most of your customizations:
comments.blade.php
- Markup for comments
content-page.blade.php
- Markup included from
resources/views/page.blade.php
content-search.blade.php
- Markup included from
resources/views/search.blade.php
content-single.blade.php
- Markup included from
resources/views/single.blade.php
content.blade.php
- Markup included from
resources/views/index.blade.php
entry-meta.blade.php
- Post entry meta information included from
resources/views/content-single.blade.php
footer.blade.php
- Footer markup included from
layouts/base.blade.php
head.blade.php
<head>
markup included fromlayouts/base.blade.php
header.blade.php
- Header markup included from
layouts/base.blade.php
page-header.blade.php
- Page title markup included from most of the files in the
resources/views/
directory
sidebar.blade.php
- Sidebar markup included from
layouts/base.blade.php
Extending templates
The normal WordPress Template Hierarchy is still intact. Here’s some examples:
- Copy
index.blade.php
toauthor.blade.php
for customizing author archives - Copy
index.blade.php
tohome.blade.php
for customizing the Home page if you’re showing the latest posts (under Reading Settings) instead of a static front page - Copy
index.blade.php
toarchive-gallery.blade.php
for customizing the archive page for a custom post type registered asgallery
- Copy
page.blade.php
tofront-page.blade.php
for customizing the static front page - Copy
page.blade.php
topage-about.blade.php
for customizing a page called About
Blade Templates
Sage uses Laravel’s Blade templating engine.
Passing data to templates
Sage includes a sage/template/{$class}/data
filter that can be used to pass data to templates. This is the most simple way to pass data.
add_filter('sage/template/page/data', function (array $data) {
$data['header_image'] = get_field('header_image');
$data['header_content'] = get_field('header_content');
return $data;
});
Controller can also be used to pass data to templates.
WP-CLI utility
blade-generate
is a WP-CLI package that can be used to compile, wipe, and clear Blade templates. Install blade-generate
by running:
wp package install git@github.com:alwaysblank/blade-generate.git
After installing blade-generate
you can run the following commands:
wp blade compile
wp blade clear
wp blade wipe
Theme Sidebar
Displaying the sidebar
The sage/display_sidebar
filter can be used to define which conditions to enable the primary sidebar on.
add_filter('sage/display_sidebar', function ($display) {
static $display;
isset($display) || $display = in_array(true, [
// The sidebar will be displayed if any of the following return true
is_single(),
is_404(),
is_page_template('template-custom.php')
]);
return $display;
});
Theme Functionality
The app/
directory contains all of the theme functionality. Since Sage is a starter theme, it’s okay for you to modify files within app/
to meet the needs of the site you’re building.
The PHP code in Sage is namespaced, so make sure to use namespaced functions and classes.
app/setup.php
- Enqueue stylesheets and scripts, register support for theme features with
add_theme_support
, register navigation menus and sidebars. See Theme Configuration and Setup.
app/admin.php
- Placeholder code for the WordPress theme customizer. You can also use this file for anything related to the WordPress admin.
app/filters.php
-
Add WordPress filters in this file. Filters included by default:
body_class
— add<body>
classesexcerpt_more
— add “… Continued” to excerptstemplate_include
— enable the theme wrapper- Various filters for the Blade implementation
app/helpers.php
-
Helper functions used throughout the theme:
asset_path
— used when enqueueing theme assets to provide the correct versioned asset filenamesdisplay_sidebar
— used to control displaying the sidebartitle
— used to return page titles
Deployment:
- These are the primary projects that make up the Sage workflow:
- Webpack is used as a build tool for compiling stylesheets, checking for JavaScript errors, optimizing images, and concatenating and minifying files. In previous versions of the theme we used Grunt and Gulp as our build tools.
- npm npm is a front-end package manager. Sage uses npm to pull in Bootstrap and jQuery as dependencies.
- BrowserSync with Webpack Hot Module ReplacementBrowserSync with WHR keeps multiple browsers and devices synchronized while developing, along with injecting updated CSS and JS. In previous versions of the theme we used LiveReload for injecting assets.
- the dist folder is gitignored by default. The reason for this is that it is good practice to never check compiled files into source control (it is called source control for a reason). The ideal setup would be a CI (continuous integration) server that builds the project after deployment and than pushes it onto the server. The next ideal solution is deployment on the production server itself. Of course you need to be able to install the dependencies on the server and take into account that building the project will put some strain on the server.The most straightforward solution is to built the project locally, push with Git and upload the compiled files (that are not in the Git repo) with src.
- To deploy a Sage theme you’ll need to make sure two things are covered:
- Run
composer install
from the theme directory on the remote server (if possible) - Copy over production theme assets
- Run
- What (not) to ignore if you are not building anything on the server
- Remove from
.gitignore
- The normal dependencies in vendor. But keep ignoring the dev-dependencies:
- The normal dependencies in vendor. But keep ignoring the dev-dependencies:
- Add to the main
.gitignore
(but only for deployment. you need these files in your theme repo of course)- /composer.*
- /vendor/composer/installers
- /vendor/squizlabs
- /vendor/roave
- /*.md
- wp-cli.yml
- Add to the theme
.gitignore
- /resources/assets
- .editorconfig
- .eslintrc
- .travis.yml
- LICENSE.md
- package.json
- yarn.lock
-
/vendor/roots/sage-installer
-
/vendor/squizlabs
-
/vendor/composer/installers
-
/.github
- Optionally add plugins and WordPress to your gitignore, if you want to update these from the WP dashboard on the production site
- Remove from
Bootstrap Navwalker menu
Update Dec 2018:
All you need to do is include this composer package in your Sage theme and the navwalker will be available to use.
https://github.com/MWDelaney/sage-bootstrap4-navwalker
- To install, run the following in your Sage9-based theme directory:
composer require "mwdelaney/sage-bootstrap4-navwalker"
- Include the navwalker in your
wp_nav_menu
function in the blade template for the header:{!! wp_nav_menu( array(
'menu' => 'primary',
'theme_location' => 'primary_navigation',
'walker' => new wp_bootstrap4_navwalker(),
'menu_class' => 'nav navbar-nav')) !!}
- At the top of the blade template add:
<?php namespace: app ?>
- If you want to use the ‘clean walker’, just make sure you have soil installed and activated on your site. bootstrap navs work fine with just the clean walker as long as you don’t need dropdown support.
Theme assets
The config.json
file in the assets
directory controls the different theme assets that get built. By default, Sage builds two JS files and one CSS file:
assets/stylesheets/main.scss
— primary theme CSS, barebones partials are imported to help get your styling startedassets/scripts/main.js
— primary theme JSassets/scripts/customizer.js
— theme customizer JS, used only in the customizer
Look at entry
in assets/config.json
to see how they’re built:
"entry": {
"main": [
"./scripts/main.js",
"./styles/main.scss"
],
"customizer": [
"./scripts/customizer.js"
]
}
To create additional CSS or JS files, you’ll need to:
- Create the files within the
assets/scripts/
orassets/styles/
directories - Open
assets/config.json
and add the new files toentry
in a new array. In the example below we’ve addedscripts/checkout.js
:"entry": { "main": [ "./scripts/main.js", "./styles/main.scss" ], "customizer": [ "./scripts/customizer.js" ], "checkout": [ "./scripts/checkout.js" ] }
- Enqueue the new file in
src/setup.php
In the example below we’ve added a conditional to only enqueuescripts/checkout.js
on the checkout page:/** * Theme assets */ add_action('wp_enqueue_scripts', function () { wp_enqueue_style('sage/main.css', asset_path('styles/main.css'), false, null); wp_enqueue_script('sage/main.js', asset_path('scripts/main.js'), ['jquery'], null, true); if (is_page('checkout')) { wp_enqueue_script('sage/checkout.js', asset_path('scripts/checkout.js'), ['jquery'], null, true); } }, 100);
- From the theme directory, run the build script:
# web/app/themes/your-theme-name/ $ yarn run build
3rd party packages
Example of how to add 3rd party packages* and have them included in the theme:
- From the theme directory, run:
# @ themes/your-theme-name/ $ yarn add <package name> # Install Slick carousel: $ yarn add slick-carousel
- Open up
main.js
andmain.css
to add the entry points for the package. If you’re using the Slick Carousel then your theme JS and CSS would look like:/** import external dependencies */ import 'jquery'; import 'bootstrap/dist/js/bootstrap'; // Import Slick import 'slick-carousel/slick/slick.min';
/* sage/assets/styles/main.scss */ @import "common/variables"; // Import npm dependencies @import "~bootstrap/scss/bootstrap"; @import "~font-awesome/scss/font-awesome"; // Import Slick @import "~slick-carousel/slick/slick.scss"; @import "~slick-carousel/slick/slick-theme.scss";
- After running
yarn run build
from the theme directory, your package will be built with your theme assets. Thedist
folder will contain a_/node_modules/
directory that has any assets referenced from your packages. The compiled CSS and JS will reference these assets without having to manually edit paths. - Running
yarn run build:production
will fail if 3rd party package’s relative paths are not configured before imported. In example to load Slick Carousel’s paths add the following line in your common/_variables.scss file:/* sage/assets/styles/common/_variables.scss */ // Slick Carousel font path $slick-font-path: "~slick-carousel/slick/fonts/"; // Slick Carousel ajax-loader.gif path $slick-loader-path: "~slick-carousel/slick/";
∗Note: WordPress Plugins are installed elsewhere or with Composer when using Bedrock
# @ themes/your-theme-name/
$ yarn add font-awesome
/* sage/assets/styles/main.scss */
@import "common/variables";
// Import Font Awesome from node_modules
@import "~font-awesome/scss/font-awesome.scss";
Images in template files
Use the @asset
directive to call images from template files:
<img src="@asset('images/example.jpg')">
ES6
Tips:
- If some plugin is causing problems because of lint errors, you can ignore it by putting this at the top of the file:
/* jshint ignore:start */
Recommended Forks
- Gromf — Sage with Foundation
- sage-mdl — Sage with Material Design Lite
- sage-lost-stylus — Sage with Lost Grid and Stylus
- sage-twig-theme — Sage with Twig and Timber