This project is currently a work in progress. Expect breaking API changes!
A Wordpress boilerplate created by 46cl, featuring Timber (with Twig), Composer, Bower, Gulp, Less, Browserify (with Babel as an option), icon fonts and CSS sprites generation, and project management allowing to automatically install and run your new project on your working computer.
Tested on Wordpress 4.1+
Required dependencies:
Install Homebrew and run brew doctor
. If everything seems OK, install the required packages with those commands:
brew tap homebrew/php
brew install git php56 mysql node wp-cli composer
Make sure MySQL's server is started with mysql.server start
.
That's it!
Open the wp-project.json file and fill in the title
, slug
and database
properties:
{
"title": "My new project",
"slug": "my-new-project",
"database": "mynewproject",
// ...
}
Then install the dependencies and run the installer:
npm install
npm run wp-install
If the installation failed for any reason, just run npm run wp-clean
to rollback to the previous state. It doesn't cancel the created commit but if you reached this point there shouldn't be any issues that requires a rollback.
To run a local server, use npm run wp-serve
. By default, this command will listen on 0.0.0.0:8080
, you can adjust this behaviour with two options: --host
and --port
.
npm run wp-serve -- --host=127.0.0.1 --port=8000
You can now log in the back office with the admin user and admin password.
To watch for your assets modifications, use npm run watch
.
Open the wp-project.json file and add the slug of the plugin you want to install in the plugins
array:
{
// ...
"wordpress": {
"version": null,
"plugins": [
// ...
]
}
}
For example, say you want to install Really Simple CAPTCHA, check the Wordpress.org url of the plugin and you will see the slug at the end:
https://wordpress.org/plugins/really-simple-captcha/
The slug is really-simple-captcha
, add it to the configuration file:
"plugins": [
"really-simple-captcha"
]
Run npm run wp-install
, your plugin will be installed and activated, the configuration will also be rewritten to include the last version number:
"plugins": [
"really-simple-captcha@1.8.0.1"
]
The boilerplate is provided with a theme ready to use. It leverages some redundant tasks and provides a structure for your files.
The boilerplate is provided with Bower and a Gulp configuration ready to be used to concatenate script files and compile Less, with sourcemaps. Icon fonts and CSS sprites generation also comes out of the box.
All the assets that should be compiled live in the app/
directory of your theme. The output after compilation will be saved to the assets/
directory.
You don't need to touch the gulpfile.js file to add new paths to the compilation tasks, everything lives in the gulp-paths.json file.
In this file, the %theme_path%
keyword is automatically replaced at runtime by the path of your theme, allowing you to have shorter paths in your config file and to easily rename your theme (don't forget to update the configuration if you do this).
Every path or array of paths in the configuration file will be interpreted by the gulp.src()
method (once the %theme_path%
keyword is replaced), check its documentation to understand the syntax.
Here's a simple description of the important parts:
{
// Contains the paths of the files you want to transform.
"src": {
// Contains tasks which behaviour doesn't differ between vendor and local
// files.
"common": {
// [task] Copy all the files from one directory to another.
"copy": {}
},
// Contains tasks related to the vendor files you want to transform.
"vendor": {
// [task] Concatenates and minifies stylesheets.
"stylesheets": {},
// [task] Concatenates and minifies scripts.
"scripts": {}
},
// Contains tasks related to the local files you want to transform.
"app": {
// [task] Generates icon fonts.
"icons": {},
// [task] Generates CSS sprites.
"sprites": {},
// [task] Compiles and minifies Less files.
"stylesheets": {},
// [task] Compiles and minifies ES6 files.
"scripts": {}
}
}
}
The sprites
and stylesheets
tasks are very simple to use. By using the configuration below (useless parts for the example, like the dest
object, have been stripped), you will create a new my-vendor-scripts.js
file in the assets/
directory containing Swiper and Waypoints concatenated and minified:
{
"src": {
"vendor": {
"scripts": {
"my-vendor-scripts": [
"bower_components/swiper/dist/js/swiper.js",
"bower_components/waypoints/lib/noframework.waypoints.js"
]
}
}
}
}
Note: Remember to install your dependencies before adding them to your configuration. Here you would need to run bower install swiper waypoints --save-dev
.
One thing you should do is to always include the non-minified files (JS, CSS, whatever…), they will be automatically minified and source maps will be generated, this way you will be able to see the non-minified files in your inspector.
To copy files, create a new entry in the src.common.copy
object, the key is the name of your “copy task” and the value is the path(s) to your file(s).
Say you want to use Mapbox.js, this library comes with images used by its CSS file. Simply use this configuration:
{
"src": {
"common": {
"copy": {
"mapbox": "bower_components/mapbox.js/theme/images/*.png"
}
}
},
"dest": {
"copy": {
"mapbox": "%theme_path%/assets/images/"
}
}
}
In the dest
object, we specify where we want to copy our files for the mapbox
“copy task”.
Since the source files can come from any location, the watched paths aren't configured out-of-the-box, remember to update the watch
object:
{
"watch": {
"common": {
"copy": "bower_components/mapbox.js/**"
}
}
}
This way, if you run bower update
while npm run watch
is running, the new images while be automatically copied to the assets/images/
directory.
If you have a bunch of SVG files you want to embed in a font you will need to prepare them.
Once this is done, choose a name for your font, "ico" for example, and add a new object to the icons
section:
// ...
"icons": {
"ico": {
"stylesheet-tpl": "%theme_path%/app/stylesheets/icons.less.swig",
"svgs": "%theme_path%/app/icons/ico/*.svg"
}
},
// ...
Here's some explanations:
"ico"
key is the name of your font."stylesheet-tpl"
contains a path to a template used to generate the final stylesheet associated to your fonts. The templating language is Swig, we already provide you a ready-to-use template (located at the specified path above), feel free to edit it."svgs"
is where your SVG files are located.Run npm run watch
in your console and add your new stylesheet to your HTML:
<link rel="stylesheet" href="https://github.com/46cl/wp-boilerplate/blob/master/{{ 'ico.css'|asset('app') }}">
Now you can use the corresponding classes in your HTML:
<span class="ico ico-my-icon"></span>
If you want to use the classes created for your icon font in other stylesheets, you can import the intermediate Less stylesheet in your app.less
file instead of importing the CSS file in the HTML code:
@import '../../.tmp/ico.less';
// Now you can, for example, extend the generated classes:
.title {
&:extend(.ico all, .ico-my-icon all);
}
You can generate CSS sprites through the gulp configuration. Choose a name for your sprite, "my-sprite" for example, and add a new object to the sprites
section:
// ...
"sprites": {
"my-sprite": {
"path": "%theme_path%/app/sprites/my-sprite/**"
}
},
// ...
Run npm run watch
in your console and add your new stylesheet to your HTML:
<link rel="stylesheet" href="https://github.com/46cl/wp-boilerplate/blob/master/{{ 'my-sprite.css'|asset('app') }}">
Now you can use the corresponding classes in your HTML:
<div class="my-sprite my-sprite-image1"></div>
If you want to get rid of an additional HTTP request, you can also import the stylesheet in your app.less
file:
@import '../../assets/my-sprite.css';
It is worth mentioning you can also manage retina images. In your source folder, put the biggest dimensions of your images (they will be automatically resized) and add dimensions to your configuration:
// ...
"sprites": {
"my-sprite": {
"path": "%theme_path%/app/sprites/my-sprite/**",
"dimensions": [
{"ratio": 1, "dpi": 72},
{"ratio": 2, "dpi": 192}
]
}
},
// ...
With this configuration, the retina sprite will be displayed on devices with a DPI >= 192. On other devices, a smaller sprite will be displayed.
Every scripts will be automatically passed to Babel to transpile ES6 to ES5. However, don't forget to require the polyfill if you use some methods introduced by this version of the specification, same goes if you use generators:
require('babel/polyfill');
/**
* Create a new Ajax endpoint with preconfigured headers for JSON values.
* @param string $action The action name associated to your endpoint.
* @param callable $handler The callback executed each time the endpoint is requested.
* @param boolean $isPublic Defines if the endpoint should be public or not.
*/
new App\Ajax\Endpoint($action, callable $handler, $isPublic = false);
/**
* Create a new public Ajax endpoint with preconfigured headers for JSON values.
* @param string $action The action name associated to your endpoint.
* @param callable $handler The callback executed each time the endpoint is requested.
*/
new App\Ajax\PublicEndpoint($action, callable $handler);
/**
* Save post meta data in the database, the $_POST values are automatically retrieved.
* @param integer $post_id The ID of the post.
* @param string[] $fields An array containing the name of the fields.
*/
App\Meta::savePostData($post_id, $fields);
Composer is installed with the theme, allowing you to easily add PHP dependencies. To run Composer through the command-line:
$ pwd
/home/johann/wp-boilerplate
$ cd public/wp-content/themes/your_theme_name
$ composer require vendor/name
However, if you want to use Composer straight from the root of your project, we created a command for you:
$ pwd
/home/johann/wp-boilerplate
$ npm run composer -- require vendor/name
In the configuration file of the theme (config/theme.php), you can disable/enable Wordpress features and manage versions for your assets.
Comments, pingbacks and trackbacks can easily be disabled/enabled by setting the associated key to false
/true
.
To customize the admin menu, you provide an array containing the name of the item as a key and whether it should disabled/enabled as a boolean value. For submenus, simply use nested arrays. For example, say you want to disable the Appearance menu and the Media submenu in the Settings menu, simply use this configuration:
return array(
'wordpress' => array(
// ...
'admin_menu' => array(
'themes.php' => false,
'options-general.php' => array(
'options-media.php' => false,
),
),
),
// ...
);
The keys are based on the accepted values by the remove_menu_page
and remove_submenu_page
functions.
Note: Pingbacks and trackbacks are disabled by default since they can be used as a gateway for DDoS attacks, see issue #35.
You can define versions for your assets, those will be used by the asset
Twig filter. If you define 2.2.1
for the vendor
key, all your assets included through the asset
filter with the 'vendor'
parameter will be appended with this query parameter: ver=2.2.1
. This feature is useful to force browsers to refresh their cache.
See the views/layout.twig file for an usage example of this filter.
You can access a configuration property with the App\Config::get($propertyPath)
method. For example, if you want to access to the vendor
property in the assets
array:
App\Config::get('assets.vendor');