RT Cunningham

WordPress Static Site Generator, Part 6 – The Static Generator Script

Although this is the last ingredient in the WordPress static site generator, there are still a few things you need to be aware of when you start using it.

I won’t be leaving you in the lurch. I’ll explain everything after I explain this script (to the best of my abilities).

The WordPress Static Site Generator Script

This is the entire script. I’ll try to explain it as best I can after you take a minute to review it.

<php
#
# Edit Below
#
$path                 = '/home/rtcunningham/www.rtcx.local';
$master               = $path . '/';
$new                  = $path . '/static_new/';
$real_site_url        = 'https://www.rtcx.net/';
$schema_real_site_url = str_replace('/', '\/', $real_site_url);
$user                 = 'rtcunningham';
$group                = 'rtcunningham';
$timezone             = 'America/Los_Angeles';
$user_agent           = 'WPSSG';
$page_to_skip         = 'about-rtcx';
#
# Stop Editing
#
function my_file_put_contents($fname, $fcontent, $user, $group) {
  file_put_contents($fname, $fcontent);
  chmod($fname, 0644);
  chown($fname, $user);
  chgrp($fname, $group);
}
#
# Load WordPress and Get the Local Site URL
#
include $path . '/wp-load.php';
$site_url = home_url('/');
$schema_site_url = str_replace('/', '\/', $site_url);
#
# Queue File Names
#
$queue = array();
$posts = get_posts(array('numberposts' => -1, 'orderby' => 'modified', 'post_type' => array('post','page'), 'post_status' => 'publish'));
foreach ($posts as $post) {
  if ($post->post_name == $page_to_skip) continue;
  $queue[] = $post->post_name;
}
$queue[] = 'index.html';
$queue[] = 'feed.rss';
#
# Create Pages
#
$context = stream_context_create(array('http'=>array('method'=>"GET", 'ignore_errors' => true, 'header'=>"User-Agent: " . $user_agent . "\r\n")));
foreach($queue as $item) {
  echo ".";
  $url = $site_url . $item;
  if ($item == 'index.html') $url = $site_url;
  if ($item == 'feed.rss')   $url = $site_url . 'feed';
  $page = file_get_contents($url, false, $context);
  $page = str_replace(trim($site_url, '/'), trim($real_site_url, '/'), $page);
  $page = str_replace(trim($schema_site_url, '/'), trim($schema_real_site_url, '/'), $page);
  $page = trim($page) . "\n";
  $master_page = '';
  if (file_exists($master . $item)) $master_page = file_get_contents($master . $item);
  if ($page != $master_page) my_file_put_contents($new . $item, $page, $user, $group);
}
#
# Create Sitemap
#
echo ".";
date_default_timezone_set($timezone);
$sitemap = 'sitemap.xml';
$today = date('Y-m-d');
$page = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n\t<url>\n\t\t<loc>$real_site_url</loc>\n\t\t<lastmod>$today</lastmod>\n\t\t<changefreq>monthly</changefreq>\n\t</url>\n";
foreach ($posts as $post) {
  if ($post->post_name == $page_to_skip) continue;
  $item = $post->post_name;
  if (strstr($item, '?')) continue;
  $a = explode(' ', $post->post_modified);
  $postdate = $a[0];
  $page .= "\t<url>\n\t\t<loc>$real_site_url$item</loc>\n\t\t<lastmod>$postdate</lastmod>\n\t\t<changefreq>daily</changefreq>\n\t</url>\n";
}
$page .= "</urlset>\n";
$master_page = '';
if (file_exists($master . $sitemap)) $master_page = file_get_contents($master . $sitemap);
if ($page != $master_page) my_file_put_contents($new . $sitemap, $page, $user, $group);
echo "\n";

The only section you need to edit is the section called “Edit Below”. Those parameters are exactly what I use on my Linux Mint laptop. You obviously need to change them to suit your system.

The “user” and “group” parameters are ignored on Windows (probably not on a Mac). 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 page to skip is the page slug you use for the front page. It won’t hurt anything for it to exist, but it’s wasted space.

This 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 it is.

In the Nginx location block, you’ll need to insert “default_type text/html;” just before the “try_files” line. The line is “ForceType text/html” in Apache 2.4, but I don’t know where it goes.


Using the WordPress Static Site Generator

After I publish a post, I run the script to create the files. When I connect by FTP, I transfer new images from “/ifiles” to the online “/ifiles”. Then I transfer the files from “/static_new” to the online root directory for the website. The last step is to move the files from “/static_new” to “/static_master”. With the Linux “mv” command, files get overwritten.

The script compares the files in the master directory to the database contents for each file. Only new files or those that have been changed show up in the new directory. I usually have to transfer less than 50 files (because the related posts change). FTP uploads are typically slow. If I ever switch to a fiber connection, it probably won’t matter if I upload all of them every time.

Last Notes

I’m sure there’s something I left out, somewhere along the process. If there’s a glaring omission or just something you need to know, feel free to leave a comment or contact me personally. I’ll review everything I’ve written about the WordPress static site generator at least 10 times. If I find a mistake or something I left out, I’ll fix it.

This is what works for me. It may or may not work for you. At this point, all I can say is “good luck”.


April 23, 2018
Web Development

You May Also Like: