All the power of Pug, Compass and Coffeescript, in your WordPress theme. Stop writing themes like it's 1998.
PHP HTML XSLT JavaScript Shell CSS Other
Latest commit cf7445e Jan 11, 2017 @mukkoo mukkoo committed on GitHub Author and License update


Wordless logo

Wordless is an opinionated WordPress plugin that dramatically speeds up and enhances your custom themes creation. Some of its features are:

  • A structured, organized and clean theme organization (taken directly from Rails)
  • The ability to create a new theme skeleton directly within the WordPress backend interface
  • The ability to write PHP code using the beautiful Pug templating system
  • The ability to write CSS stylesheets using the awesome Sass syntax and the Compass framework
  • The ability to write Javascript logic in Coffeescript
  • The ability to merge and compress Javascript assets using Yahoo YUI Compressor
  • A growing set of handy and documented helper functions ready to be used within your views

Build Status

Requirements, installation and configuration

Wordless will make your web development easier, faster and fun again, you will write less and be more productive; you'll love it more than anything else you've ever loved before and there will be rainbows and ponies randomly popping up everywhere. πŸ’–

But what's the catch? It needs Ruby. No I mean it, it seriously needs Ruby.

If you are not familiar with Ruby you may read the following tutorial for getting up a fully functional Ruby environment in less than 5 minutes. Otherwise, if you are already fluent in Ruby, Wordless depends on compass, sprockets and coffee-script. The coffee-script gem requires a valid javascript runtime available on your machine, see the ExecJS readme to learn about the supported ones.

Note that the production server doesn't need Ruby at all, since all the assets are precompiled by Wordless on the development machine, then deployed to production and statically served; so your production server will work with plain PHP, HTML, CSS and Javascript files and won't need anything fancier.

The RVM Way

Our recommended way to get Ruby installed on your system is RVM, the Ruby Version Manager. This beautiful project creates a tight, clean and well organized Ruby platform in your system. Moreover it's deadly easy to setup (this requires git installed):

\curl -L | bash -s stable --autolibs=enabled

Now reload your shell and install the latest Ruby version by running (this will take some time, go have a coffee or something):

rvm install 2.1.2

Whew, now you have a fully functional Ruby environment! The following oneliner will create a new gemset called wordless, install the gems wordless needs and create some handy symbolic links:

rvm use 2.1.2@wordless --create --default && \
gem install therubyracer sprockets compass coffee-script thor yui-compressor && \
rvm wrapper 2.1.2@wordless wordless compass ruby

Now you should be able to know the location of your RVM-wrapped ruby executables typing which wordless_ruby and which wordless_compass on your terminal.

The Cool Stuff

Okay, now we can get everything up and running :)

  1. Enable Apache mod_rewrite module (a2enmod rewrite) and make sure WordPress nice permalinks are enabled under the WP "Settings > Permalinks" section (for example, choose month and name)
  2. Download the Wordless plugin, drop it in the wp-content/plugins directory (be sure its directory is named 'wordless') and enable it from the WP "Plugins" section
  3. Create a brand new Wordless theme directly within the WP backend, from the WP "Appearance > New Wordless Theme" section
  4. Configure the path of your compass and ruby executables within the WP "Appearance > Wordless preferences". You can find the right paths by typing which wordless_compass and which wordless_ruby

Wordless Theme anatomy

That's a typical Wordless theme directory structure:

β”œβ”€β”€β”€β”€ index.php
β”œβ”€β”€β”€β”€ assets
β”‚Β Β    β”œβ”€β”€β”€β”€ fonts
β”‚Β Β    β”œβ”€β”€β”€β”€ images
β”‚Β Β    β”œβ”€β”€β”€β”€ javascripts
β”‚Β Β    └──── stylesheets
β”œβ”€β”€β”€β”€ config
β”‚Β Β    β”œβ”€β”€β”€β”€ initializers
β”‚Β Β    └──── locales
β”œβ”€β”€β”€β”€ theme
β”‚Β Β    β”œβ”€β”€β”€β”€ assets
β”‚Β Β    β”‚Β Β    β”œβ”€β”€β”€β”€ javascripts
β”‚Β Β    β”‚Β Β    └──── stylesheets
β”‚Β Β    β”œβ”€β”€β”€β”€ helpers
β”‚Β Β    β”‚Β Β    └──── README.mdown
β”‚Β Β    └──── views
β”‚Β Β          β”œβ”€β”€β”€β”€ layouts
β”‚Β Β          └──── posts
└──── tmp

Now let's see in detail what is the purpose of all those directories.


The index.php serves as a router to all the theme views.


if (is_front_page()) {
} else if (is_post_type_archive("portfolio_work")) {
} else if (is_post_type("portfolio_work")) {

As you can see, you first determine the type of the page using WordPress conditional tags, and then delegate the rendering to some particular view.

Theme Views (theme/views/*.pug or theme/views/*.php)

That's the directory where you'll find yourself coding for most of the time. Here you can create a view for each main page of your theme, using Pug syntax or plain PHP. Feel free to create subdirectories to group together the files. Here's what could be an example for the typical WordPress loop in an archive page:

// theme/views/posts/archive.haml
h2 Blog archive
  while have_posts()
    - the_post() render_partial("posts/single")

// theme/views/posts/_single.haml
h3!= link_to(get_the_title(), get_permalink())
.content= get_the_filtered_content()

Wordless uses Pug.php - formerly called Jade.php - for your Pug views, a great PHP port of the PugJS templating language. In this little snippet, please note the following:

  • The view is delegating some rendering work to a partial called _single.pug. Partial templates – usually just called β€œpartials” – are another device for breaking the rendering process into more manageable chunks. Partials are named with a leading underscore to distinguish them from regular views, even though they are referred to without the underscore.
  • There's no layout here, just content: the layout of the page is stored in a secondary file, placed in the theme/views/layouts directory;
  • We're already using two of the 40+ Wordless helper functions, link_to() and get_the_filtered_content(), to DRY up this view.

It looks awesome, right?

Layouts (theme/views/layouts directory)

Just like Rails, when Wordless renders a view as a response, it does so by combining the view with a layout. Within a layout, you have access to the wl_yield() helper to combine it with the main content:

doctype html
  head= render_partial("layouts/head")
    .page-wrapper render_partial("layouts/header") wl_yield() render_partial("layouts/footer")
    // jQuery and application.js is loaded by default with wp_footer() function. See config/initializers/default_hooks.php for details
    - wp_footer()

Please note that for content that is shared among all pages in your application, you can use partials directly from layouts.

Helpers (theme/helpers/*.php files)

Helpers are basically small functions that can be called in your views to help keep your code stay DRY. Create as many helper files and functions as you want and put them in this directory, they will all be required within your views, together with the default Wordless helpers. These are just a small subset of all the 40+ tested and documented helpers Wordless gives you for free:

  • lorem() - A "lorem ipsum" text and HTML generator;
  • pluralize() - Attempts to pluralize words;
  • truncate()- Truncates a given text after a given length;
  • new_post_type() and new_taxonomy() - Help you create custom posts and taxonomy;
  • distance_of_time_in_words() - Reports the approximate distance in time between two dates;

Initializers (config/initializers/*.php files)

Remember the freaky functions.php file, the one where you would drop every bit of code external to the theme views (custom post types, taxonomies, wordpress filters, hooks, you name it). That was just terrible, isn't it? Well, forget it. Wordless lets you split your code into many modular initializer files, each one with a specific target:

β”œβ”€β”€β”€β”€ backend.php
β”œβ”€β”€β”€β”€ custom_post_types.php
β”œβ”€β”€β”€β”€ default_hooks.php
β”œβ”€β”€β”€β”€ hooks.php
β”œβ”€β”€β”€β”€ login_template.php
β”œβ”€β”€β”€β”€ menus.php
β”œβ”€β”€β”€β”€ shortcodes.php
β”œβ”€β”€β”€β”€ thumbnail_sizes.php
└──── wordless_preferences.php
  • backend: remove backend componentes such as widgets, update messages, ecc
  • custom_post_types: well...if you need to manage taxonomies, this is the place to be
  • default_hooks: this are used by default wordless' behaviours; tweak them only if you know what are you doing
  • hooks: this is intended to be your custom hooks collector
  • menus: register new WP nav_menus from here
  • shortcodes: as it says
  • thumbnail_sizes: if you need custom thumbnailing sizes
  • wordless_preferences: no more to be edited. Go to the Wordless menu in the WP backend

These are just some file name examples: you can organize them the way you prefer. Each file in this directory will be automatically required by Wordless.

Locale files (config/locales directory)

Just drop all your theme locale files in this directory. Wordless will take care of calling load_theme_textdomain() for you.

Note that due to WordPress localization framework, you need to append our "wl" domain when using internationalization. For example, calling __("News") without specifying the domain will not work.

You'll have to add the domain "wl" to make it work: __("News", "wl")


Wordless has two different places where you want to put your assets:

  • Place all your custom, project related assets into theme/assets/*
  • Place all the static images and vendor assets (i.e. vendor JS plugins) into assets/*

The Fast Way

  • jQuery is included by default for you
  • write your sass in theme/assets/stylesheets/screen.sass
  • write your coffeescript in theme/assets/javascripts/

and all will automagically works! :) The long way follows


Custom stylesheets

The Wordless approach is to use screen.sass, present by default, as the aggregator of smaller sass partials. By default you have:

β”œβ”€β”€β”€β”€ screen.sass
β”œβ”€β”€β”€β”€ _post.sass
β”œβ”€β”€β”€β”€ _site_header.sass
└──── _tinymce.sass

where screen.sass contains:

  @import "site_header"
    @import "tinymce"
    @import "post"

Every @import will insert in that exact line the content of the called partial, where partials are named _post.sass and just called post.

This will result in a single compiled screen.css. This file, starting from version 0.3, will be served using WordPress internal enqueueing function wp_enqueue_style.

At your will, you can add e.g. mobile.css or print.css support, going in config/initializers/default_hooks.php and extending the default function such as

function enqueue_stylesheets() {
  wp_register_style("screen", stylesheet_url("screen"), false, false);
  wp_register_style("print", stylesheet_url("print"), false, false);

then write your code into theme/assets/stylesheets/print.sass

Vendor stylesheets (or how to include assets only in a specific view)

Say that you have a jQuery plugin shipped with custom css, ok? Take the vendor-plugin.css and drop it inside assets/stylesheets folder; then include the assets in your views using stylesheet_link_tag() helper.

= stylesheet_link_tag("vendor-plugin")

Usually you want css to load in the _head.html.haml partial, but you can get it inside any view or partial. This will produce the following HTML, pointing to the assets/stylesheets directory:

<link href="/wp-content/themes/YOUR_THEME/assets/stylesheets/vendor-plugin.css"
      media="all" rel="stylesheet" type="text/css" />


Custom javascripts

The Wordless approach is to use theme/assets/javascripts/, present by default. This file, starting from version 0.3, will be served using WordPress internal enqueueing function wp_enqueue_style.

At your will, you can add support to other files, going in config/initializers/default_hooks.php and extending the default function such as:

function enqueue_javascripts() {
  wp_register_script("jquery", '', '', false, true);
  wp_register_script("application", javascript_url("application"), '', false, true);
  wp_register_script("myjs", javascript_url("myjs"), '', false, true);

then write you code into theme/assets/javascripts/

Vendor stylesheets (or the way to include assets only in a specific view)

Say that you have a jQuery plugin to load, ok? Take the vendor-plugin.js and drop it inside assets/javascripts folder; then include the assets in your views using javascript_include_tag() helper.

= javascript_include_tag("vendor-plugin")

You can get it inside any view or partial. This will produce the following HTML, pointing to the assets/javascripts directory:

<script src="/wp-content/themes/YOUR_THEME/assets/javascripts/vendor-plugin.js"

Smart serving assets

If Wordless can't find the static files in assets/stylesheets/*.css, it will search for *.sass or *.scss files inside theme/assets/stylesheets and automatically compile them. In a similar fashion, if Wordless can't find the static files in assets/javascripts/*.js, it will search for *.coffee files inside theme/assets/javascripts and compile them.

To make things faster, Wordless handles nicely precompilation caching, so a new compile will happen only if the file itself really changed since the last recompilation.

Production environement

Before going production (or staging), you have to compile your assets in order to statically serving them. You will be definitely interested in wordless-gem, which can reduce this boring task to a one liner ;)

Additional recommended plugins and tools

Wordless is not meant to be a bloated, all-included tool. This is why we recommend adding some other plugins to get the most out of your beautiful WP developer life.

  • We are developing Wordless-extender. A little plugin, that brings our collection of favorite plugins and let you set up some constants in wp-config.php useful in hardening the WP installation. At the moment is not yet well documented and absent from repository, but we are moving fast, so keep follow!

  • Wordmove: a great gem (from yours truly) to automatically mirror local WordPress installations and DB data back and forth from your local development machine to the remote staging server;

  • Wordless-gem: the CLI sheriff for your Wordless theme! Compile and clean assets, create new WP installation, a new wordless theme and let you set up a deploy command in order to easily deploy your site, collaborating with Wordmove, with a wordless deploy -r

Known problems and limitations

  • Wordless has not been tested on Windows machines
  • From WP 3.2 WordPress has ceased to support PHP4, and so does Wordless
  • Documentation still to be written
  • The routing part can be drammaticaly improved to make it more readable and DRY
  • This is go-ahead software, everything is subject to change :) but you can pull code from tagged commits (stable)

Code documentation

You can find it here. If you are intrested in contribuing to the documentation:

  • we are documenting the following at the moment (path recursive)
  • here is a list of documentation holes :9
  • go and add doc following the doxygen guides
  • pull-request your commits
  • we'll recompile the doxygen doc
  • the community will be grateful!


Wordless is available in English, German, Greek, Italian and Spanish, at the moment.

The user interface was translated by Wasilis Mandratzis-Walz (German and Greek), David Mejorado (Spanish).

Your help is welcome! Add your own language using Transifex.

Need more tools?

Visit Wordpress Tools.

Third Part Libraries


made with ❀️ and β˜•οΈ by weLaika


(The MIT License)

Copyright Β© 2013-2015 weLaika

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the β€˜Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.