RT Cunningham

WordPress Static Site Generator [Updated for 2019]

WordPress Static Site Generator This is an attempt to describe the WordPress static site generator I’ve developed over time. The idea is to develop your website using web development tools on your home computer.You use scripts and other software to turn the pages and posts into static pages and then upload them to your online web server.

The wpssg.zip file contains the PHP files I reference in this article. Please download it, unzip it and load the PHP files in a text editor. Certain items will make more sense if you follow along.

Using a WordPress Static Site Generator

I hosted my website using WordPress the normal way for years. I started developing the WordPress static site generator when I got tired of the brute force login attacks and the constant barrage of comment spam. Although I solved all those problems eventually using other techniques, I continued to develop it.

Doing things this way means you no longer need to host a database server. With static pages, there’s nothing available to attack. You can ignore your website for days, weeks or months without having to worry about someone hacking into it. The best thing about all this is that static websites can be hosted anywhere.

Most dynamic features can’t be converted to static. If you need dynamic features, especially for display purposes, a static website is not your best option.


While I’m using the Linux Mint operating system on my home computer, you’re probably using something else. If you’re using Linux, it’s best to install Apache or Nginx, PHP and MySQL (or a compatible replacement) just like you would with an online server. Otherwise, you should use a software stack designed specifically for your operating system.

I recommend Nginx over other web servers. It serves static files like nobody’s business. It’s also incredibly easy to configure once you become familiar with it. I’ve been using Nginx both online and offline for years. It’s been so long, in fact, that I can’t remember how to work with Apache.

There’s a good tutorial at DigitalOcean for a LEMP stack using Ubuntu 18.04, which will work for a local web server as well as an online one. For Windows, you can use the software provided for it at the Nginx website, the PHP website and the MySQL website. I described how I set it up on Windows when I wrote about my Homegrown CMS (which I’m still working on, by the way). I installed everything but MySQL at the time.

You need a good text editor. I like Geany for Linux and Notepad++ on Windows. You may or may not need an FTP client and you may or may not need an SSH client. It depends on how you intend to transfer files to the online web server. I like FileZilla as my FTP client and I like PuTTY as my SSH client. There are other ways to transfer files that I’m not familiar with.

Your Domain Name and Your Hosts File

No matter what your online domain name happens to be, you’ll need a local domain name for the WordPress software. You can use “”, “localhost” or a custom domain name (I prefer a custom domain name). If you want to use a custom domain name, you’ll have to edit your computer’s host file. On Linux, it’s “/etc/hosts” and on Windows, it’s “C:WindowsSystem32Driversetchosts”.

You only need to add a single line to the hosts file: example.local www.example.local

I replace the “.net” of my online domain name with “.local” for my local domain name. When the WordPress static site generator script runs, it will replace the “.local” TLD with the “.net” TLD.

Once you have your local web server running, you need to install WordPress and set it up properly. Don’t attempt to set it up with SSL/HTTPS. It’ll cause you nothing but grief. The WordPress static site generator script will convert it anyway. Next, get a theme you like and make sure there’s nothing dynamic going on with it.

The WordPress Configuration File

Copy the “wp-config-sample.php” to a “wp-config.php” file in the WordPress root directory. You only need to make the changes I’m mentioning. The other settings in the file won’t make a difference in an offline environment.

Create a blank database. You’ll need the name, the user and the password for it. The original uploads directory for media files won’t exist on your static site. You’ll have to change the location by adding a line like this just below the other “define” lines:

define('UPLOADS', 'uploads');

You can use anything in place of the second “uploads”. I use “ifiles” on my sites. From the root directory, create your new uploads directory. You’ll need to add it the same way at your online web server. After this, you need to load WordPress and log in (http://example.local/wp-login.php). You need to configure the settings next.

The WordPress Settings

In Settings/General, enter your site title and use the local domain name URL for both the WordPress address and the site address (without trailing slashes). Even though your e-mail address isn’t going to be used for anything, the CMS requires it. Select your timezone. Adjust the other date and time settings as necessary.

In Settings/Writing, remove anything in the “Update Services” block, if that block is visible. If you want to ping online services, you can use the Pingshot service provided by FeedBurner. I’ll explain it later.

In Settings/Reading, select static post and use the “Sample Page” for it. You can always change it later. WordPress will automatically use it as the front/index page. Leave the posts page as is, with nothing selected. Leave search engine visibility checked. Check it if it’s unchecked for some reason.

In Settings/Discussion, make sure every check box is unchecked. You won’t be notifying other blogs and you can’t receive link notifications. You won’t be using the WordPress comment system at all. Third-party comment systems are available and I recommend Disqus.

In Settings/Media, make sure the check boxes are unchecked. That’s the way they should be by default but aren’t.

In Settings/Permalinks, click on the radio button for “Post name”. Then, click on the radio button for “Custom Structure”. Finally, remove the trailing slash in that input box. The input box should contain “/%postname%” only. You’ll understand this later on.

Follow the instructions in Settings/Privacy. There’s too much involved for me to explain any of it.


You only need a few plugins:

If you’re concerned about search engine optimization, you also need “Broken Link Checker” and “Yoast SEO”.

I personally recommend “Contextual Related Posts”. That is, until you use something like Google’s Matched Content with AdSense.

Your Theme’s Function File

The functions I’m referencing are to be added to your theme’s “functions.php” file, if one already exists (remove the PHP opening tag). Otherwise, use it as a new file. These are the sections:

Remove Lines from Head. These functions remove some lines WordPress automatically adds to most theme files.

Output Buffering. This section lets you change the output before it even appears. Use it to remove other lines and change existing lines.

Change Taxonomy Separators. WordPress uses the slash character (“/”) to make permalinks pretty. It also uses it to separate taxonomy bases names from the taxonomies (like /author/ and /category/). This section changes the separator to a dash (or hyphen). I did not include a line for /tag/. Since the pages have to created manually, you would be spending more time creating blank pages than anything else.

Page Priority Over Taxonomy. This section lets you create one page for each taxonomy page. A page starting with “category-” will take priority over the automatically generated page that corresponds to it. With this ability, you can include anything you want on the taxonomy pages, including various shortcodes.

Article List Shortcode. This section provides the [article-list] shortcode. You can see the results by looking at my Article List page (other than the text and the title).

Category List Shortcode. This section provides the [category-list] shortcode. You can see the results by looking at my Category List page (other than the text and the title).

Category Page Shortcode. This section provides the [category-page] shortcode to be used for every category page. You have to create one page for each category and place this shortcode on it. The slug for a category page must start with “category-“. It won’t work correctly if the category isn’t created before the page.

WordPress Static Site Generator Script

You can probably understand most of the script without me explaining every detail.

The “user” and “group” parameters are ignored on Windows. Leaving them in place won’t hurt anything. The user agent can be anything you want it to be. WPSSG just tells my logs what it is. The “real_index_page” is the page slug you use for the front page (“sample-page” above). It won’t hurt anything for it to exist, but it’s wasted space.

The script will create files without any extensions, except for “index.html” and “feed.rss”. That isn’t a problem with WordPress. It’s a problem at the online web server. The web server won’t know what file type to use.

At the Nginx server level, you’ll need to insert “default_type text/html;” and “include /etc/nginx/mime.types;” before any location blocks. For whatever reason, when changing the default type, the “types” directive stops working.

WordPress Static Site Generator Procedures

When I run the script, it creates files in the “/static-new” directory. After I upload the new files to the server, along with any new images, I move the new files to the “/static-master” directory,

I use FeedBurner for RSS feed distribution. That’s the purpose of the “/feed.rss” file. Even if you choose not to use FeedBurner, you can use that file as a link on your website. Here are a few rewrites to redirect all feeds to that single file:

rewrite ^/comments/feed$ https://feed.rss permanent;
rewrite ^/comments/feed/ https://feed.rss permanent;
rewrite ^/feed$ https://feed.rss permanent;
rewrite ^/feed/ https://feed.rss permanent;

If you’d rather use FeedBurner, create an account there, change the destination and wrap it in these lines:

if ($http_user_agent !~* feedburner) {


The script creates the “index.html” file, the “feed.rss” file and the “sitemap.xml” file to go with the rest of the new files. The only file you need to create manually is the “robots.txt” file, with these lines to start with:

User-agent: *
sitemap: your-site-url/sitemap.xml

Unless you use a redirect to the home page for it, you should create a “/author-your-user-name” along with the category pages. Most WordPress themes include a link to it.

Disqus Comments

A static website doesn’t include a commenting system. You can add Disqus by creating an account there and adding this code to your “functions.php” file:

add_filter('the_content', 'add_disqus');
function add_disqus($text) {
$text .= '

return $text;

Change “your-site-url” to your site URL and change “your-account” to your Disqus account.

An Updated WordPress Static Site Generator

To be clear, this is an update. I wrote the original tutorial in multiple articles years ago and then rewrote it in six articles in 2018. This is all of them combined and corrected.

The WordPress Static Site Generator will probably have to be tweaked to be 100 percent correct for your specific website. You should view the output before relying on it. Make sure there are no references to “wp-” anything, even if that means copying theme support files into an “assets” directory like I use (feel free to look at the source of this page).

If you have any issues with anything, feel free to contact me.

Share: Facebook | Twitter

👤 RT Cunningham
📅 April 11, 2019
🗁 Web Development