So I learned about this Grunt thing yesterday after I discovered my own “why”: creating WordPress theme to be submitted to manually is an unpleasant experience. Copy the file, remove all the file system such as .DS_Store, zip it, upload it to, tells me that there’s file system left, repeat the process, well you get the point.

I wish I can automate that process.

And automation is what Grunt is all about. Boy I should’ve learned Grunt way much sooner.

What needs to be done

After spend some time to learn how to use Grunt and what I can use it for, these are things I wish to automate when creating theme’s .zip file for submission:

1. Preparing .pot files for translation

I previously uses Poedit for making .pot files for translation. I don’t quite like what I have to do to make the .pot files:

  1. Create new project
  2. Editing project’s properties, adding source keywords
  3. Updating pot files based from source
  4. Save as pot files

Nah. Too much steps.

2. Converting into readme.txt

GitHub uses for repository description while uses readme.txt. Actually, you can use readme.txt for GitHub repository as well, but it’ll be displayed as this unparsed markdown text:

readme.txt at GitHub repository

In comparison, if you use instead of readme.txt, here’s how it looks. A parsed markdown text: at GitHub repository

So the ideal setup would be: having at the theme’s repository, but when submitting the theme to the repository, it needs to be converted into readme.txt.

Note: Why don’t keep both version? The first reason is it’s repetitive. The second reason is I’ve done that: theme reviewer ended up suggesting me to remove the .md version.

3. Creating .zip file to be submitted

As what I’ve said above: the manual process is repetitive and prone to error of missing some file system which should be deleted.

Here comes the solution: Grunt

Grunt is a javascript task runner which helps you automate repetitive things on your project . Think of it as SIRI on iPhone1 but instead of pressing the home button and command your iPhone with your voice, here’s what you do with Grunt:

  1. you open terminal
  2. cd to your theme’s directory
  3. type grunt your_task_name_here.

You need to setup the task before summoning the task tho. You can read more what Grunt is on its site. There are many tutorial about Grunt for beginner on the web, but I found these three articles are really helpful for me:

  1. Chris Coyier 2  at 24ways: Grunt for People Who Think Things Like Grunt are Weird and Hard
  2. Lee Mason at Tuts Plus: Using Grunt with WordPress Development
  3. Mike Cunsolo at Smashing Magazine: Get Up And Running With Grunt

How I use Grunt (For The Time Being)

I uses my recent theme, Patio, for trying Grunt. After installing grunt on my project folder and installing required npm packages needed (click here to see npm packages I use as dependencies at package.json), here’s how my Gruntfile.js looks:

It basically does what I explained on “What needs to be done” section above. I register two tasks: release for making .pot file for translation and build for creating .zip file of the theme.

While the release task is pretty straightforward, these are what build task does:

  1. Updating the .pot file
  2. Removing directory called /build (if there’s any)
  3. Copying into /build directory and convert it into .txt
  4. Copying the content (files and folders) of the theme except the defined files (basically filesystems) into /build directory
  5. Removing directory called /release (if there’s any)
  6. Compressing /build directory into and place it inside /release directory
  7. Removing /build directory

After the task is completed, I can open /release directory, and upload file inside it into repository.

That’s pretty much how I use Grunt for preparing theme to be submitted to Do you have any suggestion to improve it? An early explanation tho: I intentionally not minify and concatenate css/js files for these two reasons:

  1. Less assets to be registered / deregistered if child theme wants to do so
  2. I prefer it to be done via caching or optimization plugin.

What’s your thought on it?

Update [April 27th, 2015]

After discussing the code with Satrya through comment section below, apparently there’s the more efficient way for achieving what I intended to do above:

Long story short:

  1. There’s no need to use two directory (/build and /release).
  2. Executing copy will do both copy:readme and copy:build


  1. Or IFTTT for the web or Alfred Workflow for OSX 

  2. Chris has a real talent on simplifying concepts. Hands down. 

14 thoughts on “Creating WordPress Theme’s .zip File For Submission Using Grunt

  1. I don’t know what was your reason creating two folders, I think that’s unnecessarily. I forked the code

    1. Creating/updating .pot file
    2. Clean up /build folder
    3. Copy entire theme files and
    4. Zip it!

    That is just my workflow/opinion 😉

    nb: please check if you have one task with two targets and you run it in the same, you could just use the task name copy and it’ll run copy:readme and copy:build automatically

    1. I tried your forked gruntfile.js, but it exactly does what I encountered previously: the end results are the whole copy of theme file and the .zip file inside /build folder. The reason why I make two folders (build and release) is to make ensure that at the end of the process, the only files left are the compressed .zip file. I haven’t found a way to “clean all files inside /build except the .zip” XD

      I see. I just want to make sure that each step is executed one after another :)) I think your suggestion is shorter and more efficient.

      Thanks sat! 😀

        1. It still generates the same result: all theme files and the zipped file is generated inside /build:

          This is the ideal result. Only one zip file inside the directory (because we’re not going to use the rest, right?):

        2. Hmm.. the updated code should work like this.

          1. Generate .pot file
          2. Copy the files to the build folder
          3. Zip the files
          4. Clean up the theme files, so in the build folder you’d only see the .zip file

          1. The updated code you give doesn’t work like that tho 😐

            However, I’ve tweaked the code and it appears there’s a way to achieve what I intended to do:

            Basically you can make an exception when using clean task using ['!path/to/file'] in src option:

            clean: {
            	init: {
            		src: ['build/']
            	build: {
            		src: ['build/*', '!build/< %= %>.zip']
    2. One more note, grunt contrib copy has overwrite function, so it save to run copy task several times.

      1. Can you elaborate more on this, Sat? I don’t quite get it 😐

      2. Haha, please check this line, you don’t need to clean up the final folder(s), the copy function will automatically overwrite every files. 😀

        1. Ooh, I get it now :))

  2. By the way, if you need to auto generate rtl.css you can try grunt cssjanus 😉

    1. Thank you for the recommendation, I’ll give it a try. However I don’t really optimistic about auto generating RTL layout tho, absolute positioning which I use tends to be better if it is adjusted manually for RTL layout XD

  3. What a coding, really wanna know this language for basic IT, do u know where recommended place could i learn it? Thanks

  4. script is godd, thank you sir

Share Your Thought