Code compilation

First things first: using “alternative” languages is not a constraint. Wordless’s scaffolded theme uses the following languages by default:

  • PHUG for views as an alternative to PHP+HTML
  • ES2015 transpiled to JS using Babel
  • SCSS for CSS

You could decide to use plain languages, just by renaming (and rewriting) your files.

Wordless functions which require filenames as arguments, such as

<?php

render_partial("posts/post")

// or

javascript_url("application")

will always require extension-less names and they will find your files whatever extension they have.

See also

PHUG paragraph @ Using plain PHP templates

Anyway we think that the default languages are powerful, more productive, more pleasant to read and to write.

Add the fact that wordless will take care of all compilation tasks, giving you focus on writing: we think this is a win-win scenario.

PHUG

Pug is a robust, elegant, feature-rich template engine for Node.js. Here we use a terrific PHP port of the language: Phug. You can find huge documentation on the official site https://www.phug-lang.com/, where you can also find a neat live playground (click on the “Try Phug” menu item).

It comes from the JS world, so most front-end programmers should be familiar with it, but it is also very similar to other template languages such as SLIM and HAML (old!)

We love it because it is concise, clear, tidy and clean.

A snippet of a minimal WP template
h2 Post Details
- the_post()
.post
  header
    h3!= link_to(get_the_title(), get_permalink())
  content!= get_the_content()

Certainly, becoming fluent in PUG usage could have a not-so-flat learning curve, but starting from the basics should be affordable and the reward is high.

Who compiles PUG?

When a .pug template is loaded, the wordless plugin will automatically compile (and cache) it. As far as you have the plugin activated you are ok.

Important

By default, you have nothing to do to deploy in production, but if performance is crucial in your project, then you can optimize. See PHUG optimizer for more information.

JS and SCSS

Here we are in the Webpack domain; from the compilation point of view there is nothing Wordless-specific but the file path configuration.

Configuration is pretty standard, so it’s up to you to read Webpack’s documentation. Let’s see how paths are configured in webpack.config.js.

Paths

Paths are based on the Wordless scaffold. Variables are defined at the top:

webpack.config.js
2
3
4
5
const srcDir = path.resolve(__dirname, 'src');
const dstDir = path.resolve(__dirname, 'dist');

const BrowserSyncPlugin = require('browser-sync-webpack-plugin');

and are used by the entry and output configurations:

webpack.config.js
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
      return object;
    }, {}),

    output: {
      filename: "javascripts/[name].js",
      path: dstDir,
      publicPath: '../'
    },

    devtool: envOptions.devtool,

    module: {
      rules: [
        {
          test: /\.(js|es6)$/,
          exclude: /node_modules/,

CSS will be extracted from the bundle by the standard mini-css-extract-plugin

webpack.config.js
 99
100
101
          {
            from: path.join('**/*'),
            to: path.join(dstDir, imageFolderName, '[path]', '[name][ext]'),

Inclusion of compiled files

Wrapping up: the resulting files will be

  • dist/javascripts/application.js
  • dist/stylesheets/screen.css

As far as those files remain as-is, the theme will automatically load them.

If you want to edit names, you have to edit the WordPress asset enqueue configurations:

config/initializers/default_hooks.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php

// This function include main.css in wp_head() function

function enqueue_stylesheets() {
  wp_register_style("main", stylesheet_url("main"), [], false, 'all');
  wp_enqueue_style("main");
}

add_action('wp_enqueue_scripts', 'enqueue_stylesheets');

// This function include jquery and main.js in wp_footer() function

function enqueue_javascripts() {
  wp_enqueue_script("jquery");
  wp_register_script("main", javascript_url("main"), [], false, true);
  wp_enqueue_script("main");
}

add_action('wp_enqueue_scripts', 'enqueue_javascripts');

// Load theme supports
// See http://developer.wordpress.org/reference/functions/add_theme_support/
// for more theme supports you'd like to add. `reponsive-embeds` is on by
// default.
function wordless_theme_supports() {
  add_theme_support('responsive-embeds');
}
add_action('after_setup_theme', 'wordless_theme_supports');

Note

The stylesheet_url and javascript_url Wordless’ helpers will search for a file named as per the passed parameter inside the default paths, so if you use default paths and custom file naming, you’ll be ok, but if you change the path you’ll have to supply it using other WordPress functions.

Multiple “entries”

“Entries” in the WebPack world means JS files (please, let me say that!).

Wordless is configured to produce a new bundle for each entry and by default the only entry is main

main.js
require('./javascripts/application.js');
require('./stylesheets/screen.scss');

As we’ve already said having an entry which requires both JS and SCSS, will produce 2 separate files with the same name and different extension.

Add another entry and producing new bundles is as easy as

  • create a new file
  • write something in it, should it be a require for a SCSS file or a piece of JS logic
  • add the entry to webpack config
const entries = ['main', 'backend']
  • include somewhere in your theme. For example in the WP’s asset queue in default_hooks.php

    function enqueue_stylesheets() {
        wp_register_style("main", stylesheet_url("main"), [], false, 'all');
        wp_register_style("backend", stylesheet_url("backend"), [], false, 'all');
        wp_enqueue_style("main");
        wp_enqueue_style("backend");
    }
    
    function enqueue_javascripts() {
        wp_enqueue_script("jquery");
        wp_register_script("main", javascript_url("main"), [], false, true);
        wp_register_script("backend", javascript_url("backend"), [], false, true);
        wp_enqueue_script("main");
        wp_enqueue_script("backend");
    }
    

    or add it anywhere in your templates:

    header
        = stylesheet_link_tag('backend')
    footer
        = javascript_include_tag('backend')
    

Browserslist

At theme’s root you’ll find the .browserlistsrc file.

By default it’s used by Babel and Core-js3 to understand how to polyfill your ES2015 code. You can understand more about our default configuration reading Babel docs at https://babeljs.io/docs/en/babel-preset-env#browserslist-integration

Stylelint

We use Stylelint to lint SCSS and to enforce some practices. Nothing goes out of a standard setup. By the way some spotlights:

  • configuration is in .stylelintrc.json file
  • you have a blank .stylelintignore file if you may need
  • yarn lint will launch the lint process
  • if you use VS Code to write, we ship .vscode/settings.json in theme’s root, which disables the built-in linters as per stylelint plugin instructions. You may need to move those configurations based on the folder from which you start the editor.