Chisel is a Yeoman generator for setting up and developing front-end and WordPress projects.
- Features
- Installation
- Project setup
- Project structure
- Front-end development
- WordPress development
- Tutorials
- License
Chisel allows to create 2 projects types - front-end and WordPress projects with front-end.
- Gulp build system
- Browsersync
- Twig templating engine
- SCSS with ITCSS architecture
- webpack
- ES6 with Babel
- gulp-rev support
- stylelint
- Prettier
- ESLint with config tailored for Chisel and Prettier synced together for consistent and hassle free code formatting
- HTML validation with htmlhint
- optional jQuery
WordPress projects include all features of front-end projects plus:
- automatic WP-CLI based WordPress and plugins installation
- automatic Timber library installation to support Twig templates
- Chisel starter theme with the same workflow as for front-end projects
- WordPress pages generation from command line
The following software needs to be installed if you want to setup and develop projects with Chisel. These installations need to be done just once so you can skip this section if you have the software already installed.
Install Node.js so you can work with npm
, Node package manager. Version 4.5+ is required.
Install Yeoman and Chisel globally.
npm install -g yo generator-chisel
If you want to update your existing Chisel installation to the latest version, run:
npm update -g generator-chisel
If you want to develop WordPress projects, you need to install Apache, PHP and MySQL. The easiest option is to use development environments like MAMP or XAMPP but you can also customize your development environment on Mac.
Chisel is using WP-CLI for most WP-related operations. WP-CLI is using mysql
and mysqlcheck
binaries, so you need to have mysql
and mysqlcheck
binaries in your $PATH
.
This step is optional but highly recommend if you develop WordPress projects. It will ensure that each new local development domain will work out of box on your computer and you won’t have to edit hosts
and httpd-vhosts.conf
files every time. This is achieved by setting up wildcard virtual hosts and DNS.
For detailed instructions how to set this up for your OS check out our wiki page.
Create new project directory and change your working directory to it:
mkdir project-name && cd $_
Run Chisel from the project directory
yo chisel
Insert project name (you can use the default one based on the working directory name), author and select Front-end only project type. Select additional front-end features if you need them and wait until installation is complete.
Note: To speedup installation process we recommend using Yarn. Chisel will automatically detect it and run if possible. Otherwise it falls back to default NPM install
If you are joining development of an existing front-end project which was already set up with Chisel, you don't have to set it up again. Follow these steps:
- Clone repository
- Run
npm install
oryarn
- Run
npm run build
andnpm run dev
Create new project directory and change your working directory to it:
mkdir project-name && cd $_
Run Chisel from the project directory
yo chisel
Insert project name (you can use the default one based on the working directory name), author and select WordPress with Front-end project type. Select additional front-end features if you need them.
Note: To speedup installation process we recommend using Yarn. Chisel will automatically detect it and run if possible. Otherwise it falls back to default NPM install
Setup your WordPress as follows:
- Enter title for the new site: title of your WordPress website
- Enter URL: the URL at which your WordPress project runs, currently Chisel only works with the default value
- Enter admin user: WordPress admin user, a different name than
admin
is suggested to increase security - Enter admin password: WordPress admin user password
- Enter admin email:
- Where do you want to place the 'src' folder: position of the src folder with styles, scripts and assets - either the root folder or theme folder
- Enter the database host:
127.0.0.1
- Enter the database port:
3306
- Enter the database name: the project database name
- Enter the database user: user who can access the database
- Enter the database password: password for the user
Select optional plugins which should be installed from the list and wait until installation is complete.
We recommend setting up wildcard virtual hosts and DNS so your project domain works out of box.
If you haven’t set them up, you will have to add project domain to your hosts
file
127.0.0.1 project-name.test
Then use automatically generated dev-vhost.conf
and add it to the Apache httpd-vhosts.conf
file or add
IncludeOptional /path/to/projects/*/dev-vhost.conf
in your Apache configuration to automatically load configuration for multiple projects.
If you are joining development of an existing WordPress project which was already set up with Chisel, you don't have to set it up again. Follow these steps:
- Clone the repository
- Create database
- Run
yo chisel:wp-config
, it will create wp-config-local.php and generate dev-vhost.conf (if you need it) - Run
npm install
oryarn
andnpm run build
- Import DB dump or enable WP Sync DB plugin and use it to import database and files. Check out the wiki page explaining how you case use WP Sync DB plugin to migrate database.
Before starting actual development get familiar with the project structure generated by Chisel.
The file structure in front-end projects looks like this:
- dist - distribution files are automatically generated here, this is where you check your work in a browser.
- gulp - Gulp tasks configuration
- node_modules - Node.js modules for various Gulp tasks, usually you don’t have to do anything about this folder
- src - source files, development is done here
- assets - static asset files (images, videos, fonts, etc.) - everything from this directory will be copied to dist folder
- styles - Sass files with ITCSS structure
main.scss
- main file where other stylesheets are imported, do not write styles directly to this file- settings – used with preprocessors and contain font, colors definitions, etc.
- tools – globally used mixins and functions. It’s important not to output any CSS in the first 2 layers.
- generic – reset and/or normalize styles, box-sizing definition, etc. This is the first layer which generates actual CSS.
- elements – styling for bare HTML elements (like H1, A, etc.). These come with default styling from the browser so you can redefine them here.
- objects – class-based selectors which define undecorated design patterns, for example media object known from OOCSS
- components – specific UI components. This is where majority of your work takes place and our UI components are often composed of Objects and Components
- utilities – utilities and helper classes with ability to override anything which goes before in the triangle, eg. hide helper class
- scripts
app.js
- main JavaScript application file where other modules are importedgreeting.js
- a sample JS module, delete or replace this one with your functionality
- templates - Twig templates
layouts/base.twig
- base layout which is extended in other templateslayouts/page.twig
- a template from which the other pages are generated*.twig
- separate twig page templates
- index - images and styles for the project index
.babelrc
- Babel configuration file.editorconfig
- EditorConfig configuration file to achieve consistent coding style.eslintignore
- ESLint ignore file.eslintrc.yml
- ESLint configuration file to achieve consistent JavaScript coding style (you can update it to your preference).gitattributes
- Git configuration file to force Unix line ending in text files.gitignore
- default Git ignore files and folders.htmlhintrc
- HTMLHint configuration file.stylelintignore
- stylelint ignore file.stylintrc.yml
- stylelint configuration file to achieve consistent CSS coding style (you can update it to your preference).yo-rc.json
- Yeoman generator configuration fileindex.html
- project index with project pages listedgulpfile.js
- Gulp configuration filepackage.json
- project metadata and dependenciesREADME.md
- project readme, you can use it for the project documentation
On a typical project, you will work in src
folder and check your work in dist
folder so you don’t have to touch other files.
File structure in WordPress projects is almost identical to the front-end projects with the following differences:
dist- dist folder is moved to the theme folder (see below)- src
templates- templates are stored in the templates directory inside the theme directory because they are interpreted dynamically by WordPress and Timber, not built by Gulp like in non-WP projects
index- project index files are not usedindex.html- project index is not used- wp - WordPress installation
- wp-content
- themes
- your-theme
- dist - dist folder where CSS, JS and assets files are built
- Chisel - various classes used to extend or add new functionality to your theme
- templates - Twig templates
index.php
- Chisel starter theme filesfunctions.php
etc.
- your-theme
- themes
- wp-admin
- wp-includes
wp-config-local.php
- your local WordPress configuration file (see below)
- wp-content
dev-vhost.conf
- automatically generated virtual host configuration (not needed if you use wildcard virtual hosts)
WordPress wp-config.php
file is altered to provide support for local configuration. All settings except Authentication Unique Keys and Salts, database charset and ABS_PATH can be set in wp-config-local.php
file for purposes of local development. The file is added automatically to .gitignore
and should not be committed and stored on the production server.
If there is wp-config-local.php
file available in main WordPress directory then the environment is recognized as local and configuration from this file is used. If it doesn't exist then settings from wp-config.php
are used.
If you prefer having the src
folder in your theme folder, choose this option when setting up the project. If you haven't and would like to move it manually, follow these steps:
- Move the
src
folder to the theme folder -wp/wp-content/themes/your-theme
- Change
chisel.src.base
property on line 13 inpackage.json
towp/wp-content/themes/your-theme/src
Once your project is setup, you need to add pages you will be working on to it. From the command line type:
yo chisel:page "Page Name"
for example
yo chisel:page "Home"
You can also create multiple pages at once by separating page names with space:
yo chisel:page "Home" "About Us" "Contact Us" "News"
When you have the basic setup done, you can start development. To re-compile Twig, SCSS and JavaScript files in real time you can use default task. Type
npm run dev
and this will start a task that will watch for changes in files and recompile them as needed.
Additionally, development server will be started and Browsersync scripts injected. If you'd like change Browsersync configuration, you can do so in gulp/tasks/serve.js
, for example here we've changed notifications and browser opening:
var browserSyncConfig = {
server: './',
ghostMode: false,
online: true,
notify: false, // Don't show any notifications in the browser.
open: false // Stop the browser from automatically opening
}
During development main.css
(unminified) and app.bundle.js
are linked in HTML. This is achieved by custom Twig function revisionedPath
which updates assets path depending on whether the watch or build tasks are running.
To rebuild the whole project and create new revisions of styles and scripts using gulp-rev
, use the build task again
npm run build
When npm run build
is run, first the dist
folder is cleaned and then build tasks are run in particular order:
styles-build
builds minified styles and creates a stylesheet revision by appending content hash to the filename. Then it createsrev-manifest.json
with original and revisioned file nameslint
runs EsLintscripts-build
runs webpack and createsapp.bundle.js
revision by appending content hash to the filename. Then it updates existingrev-manifest.json
with the original and revisioned filename.- Finally,
templates-build
reads the newly createdrev-manifest.json
and builds HTML files from Twig templates, while linking revisioned files using therevisionedPath
function.
Prettier comes preinstalled with Chisel however it's synced with Eslint only if ES6 with Babel has been selected. It's one of the reasons why choosing ES6 will result in the best coding experience. One of the easiest ways to use Prettier is to install a plugin for your favourite editor. See "Editor Integration" section on Prettier's homepage.
One of the known issues we encounter while front-end development is usage of jQuery plugins like flexslider
alongside webpack module bundler.
The usual solution to that problem can be treated this way:
- Install
jquery
node-module if you haven't done it yet. This is needed because many jQuery plugins have a check if they run inside a module bundler and requirejquery
to be a node-module, but they tend to bind themselves to global$
object either way.
npm install --save jquery
- Make jQuery global (for various reasons)
window.jQuery = window.$ = require('jquery');
- Require plugin
require('flexslider'); // Usually they bind to global jQuery object
From time to time you may stumble upon legacy jQuery plugin or one which just doesn't want to play nice with webpack. In such case you can setup the project to place jQuery and its plugins outside of the main bundle.
Make sure to choose jQuery when asked about additional front-end features and then agree to configure vendor bundle for jQuery plugins. Example:
? Select additional front-end features: ES6 with Babel, jQuery
? Would you like to configure vendor bundle for jQuery plugins? Yes
You can try following steps:
- Check if jQuery is installed. In case it isn't go ahead with
yarn add jquery
ornpm install jquery --save
depending on which tool you use. - Open up
webpack.chisel.config.js
in the root directory and make sure following entry is present:
externals: {
jquery: 'window.jQuery',
},
- Make sure that path to jQuery is present in
vendor.json
:
[
"/node_modules/jquery/dist/jquery.js"
]
- Done!
This setup will allow you to place plugins inside special src/scripts/vendor
directory. Mind they won't be picked up automatically! You need to add the plugin name in the src/scripts/vendor.json
file. Assuming that you've placed select2.full.min.js
inside the vendor, the vendor.json file should look like this:
[
"/node_modules/jquery/dist/jquery.js",
"select2.full.min.js"
]
So, to recap:
- Make sure to you've got jQuery installed.
- Place the plugin script inside
src/scripts/vendor
. - Add its name inside
src/scripts/vendor.json
. - Enjoy ;)
- It's enough to add full file name inside vendor.json. There's no need to add full path to it if the script has been placed inside
src/scripts/
. - Removing
"/node_modules/jquery/dist/jquery.js"
path will get rid of jQuery. - It's possible to refer plugins installed via NPM or Yarn using appropriate path – just like in the jQuery example:
"/node_modules/[plugin name]/[plugin-file.js]"
- When writing code it's possible to
import $ from jQuery
orvar $ = require('jquery')
and use plugins from the vendor directory. - This setup will create additional JS file called
vendor.js
. It'll be placed indist/scripts
just like the bundle file.
Use externals
option in webpack configuration. You can also try vendor plugins setup.
You can use yo chisel:page
command to add pages to your WordPress project in the same way as you do in front-end projects.
- Twig template is automatically created in
wp/wp-content/themes/[your-theme]/templates/page-{page-slug}.twig
- Page is accessible at
project-name.test/{page-slug}
To re-compile SCSS and JavaScript files in real time you can use default task. Type:
npm run dev
and this will start a task that will watch for changes in files and recompile them as needed.
Additionally, development server will be started and Browsersync scripts injected. Browsersync proxies to your WordPress instance running at project-name.test
.
Depending on where you are looking at your project, different version of styles and scripts are used:
localhost:3000
- unminified CSSproject-name.test
- revisioned and minified CSS and JS files
To create new revisions of styles and scripts using gulp-rev, use the build task:
npm run build
Chisel allows easy front-end development prior to WordPress development. Suppose you have 3 pages to develop front-end for Team
, Team Member
, Contact
.
- Add these pages from the command line like described in the previous sections
- Now your pages are accessible under
project-name.test/team/
,project-name.test/team-member/
andproject-name.test/contact/
. - Start adding HTML to relevant Twig templates. Where applicable try to use Twig syntax
- Create styles in
src/styles
. - Once you are done with front-end development a WordPress developer will add required functionality
Inside the theme there is Chisel
folder with various classes which extend WordPress or add theme functionality. It's recommended to follow the existing structure and update these classes or add new classes here instead of adding functionality directly to functions.php
.
Classes you can work with:
\Chisel\WpExtensions
- use this class to extend Wordpress (register post types, taxonomies, etc.)\Chisel\Security
- default security settings for Chisel, you can change or extend security settings here.\Chisel\Performance
- class for optimizing performance, allows to setup which JS scripts should be deferred or asynced\Chisel\Site
- this class extends\Timber\Site
class and is used to setup whole site\Chisel\Post
- this class extends\Timber\Post
class\Chisel\TwigExtensions
- this class is used to extend Twig
If you want to add new custom class, you can copy and adjust one of the existing classes. Then load your class in functions.php
Refer to Timber documentation if you are new to WordPress development with Timber.
-
ChiselPost
: you can use this function if you want to create a post class inside Twig file. As an argument you can pass post id, post object, or an array consisting of field values for the post. When creating fake post by passing an array of fields as an argument you can use_fields
key to set post meta values loaded viaget_field
method to simulate for example ACF values. You can also load existing post that will have fake fields by passing post's id withID
key:Example usage:
{% set post = ChiselPost({ 'post_title': 'Fake post title', 'post_content': 'Fake post content', '_fields': { 'special_acf_field': 'field value' } }) %}
This will create a
\Chisel\Post
object that you can use like any other post loaded from the database:<div> <h1>{{ post.title }}</h1> <p>{{ post.content }}</p> <p>{{ post.get_field('special_acf_field') }}</p> </div>
-
className
: you can use this function if you want to avoid writing long classes with multiple modifiers by hand:Example usage:
<article class="{{ className( 'c-some-post', 'red', 'type-' ~ post.type, (post.thumbnail ? 'has-thumbnail') ) }}"></article>
It will generate (assuming post of type
post
and no thumbnail):<article class="c-some-post c-some-post--red c-some-post--type-post"></article>
-
assetPath
: this function returns the real path of the asset file from thedist/assets
folder.Example usage:
<img src="{{ assetPath('images/logo.svg') }}" alt="{{ site.name }}">
-
When using ACF try to always use
get_field
method ofChisel\Post
instead of direct call to the field:Good:
{{ post.get_field('field_name') }}
Bad:
{{ post.field_name }}
Read more on the topic in ACF Cookbook
In addition to default security settings you can also:
-
Protect WP includes
Add
.htaccess
to thewp-includes
folder with the following content:<FilesMatch "\.(?i:php)$"> Order allow,deny Deny from all </FilesMatch> <Files wp-tinymce.php> Allow from all </Files> <Files ms-files.php> Allow from all </Files>
-
Protect uploads folder
Add
.htaccess
to thewp-content/uploads
folder with the following content:<FilesMatch "\.(?i:php)$"> Order allow,deny Deny from all </FilesMatch>
Note: this can break some plugins
- Craft perfect websites with Chisel
- An MVC-like WordPress Development with ACF and Timber
- Easy-to-use Code Blocks in WordPress
Chisel is licensed under MIT License.