WP Static Python
WordPress plugin that generates a static HTML site via a Python script and serves static files first (Apache/Nginx).
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/chrispengcn/wp-static-python/releases/download/v1.0.0/wp-static-python.zipReadme
WP Static Python
A lightweight WordPress plugin that generates a static HTML snapshot of your site using a Python script, and configures your web server (Apache or Nginx) to serve static files first — falling back to WordPress dynamically when a static file does not exist.
Features
- One-page admin dashboard under Settings → WP Static (or WP Static menu)
- Auto-detects your sitemap (
sitemap.xml,sitemap_index.xml,wp-sitemap.xml) - Generates copy-paste SSH commands — split into three single-line steps with a Copy button each
- Installs Python dependencies from
requirements.txtautomatically - Outputs static files into
<wordpress-root>/static/ - Provides ready-to-use
.htaccess(Apache) andnginx.confsnippets to enable "static first, dynamic fallback" - Works in Docker / local / production environments — commands use paths relative to the WordPress root
Repository Structure
wp-static-python/
├── wp-static-python.php # Main plugin file
├── README.md
├── LICENSE
└── python/
└── wpstatic/
├── wpstatic.py # Static site generator script
└── requirements.txt # Python dependencies
When you upload the plugin ZIP to WordPress, this whole folder is extracted to wp-content/plugins/wp-static-python/ and is ready to activate.
Requirements
- WordPress 5.0+
- PHP 7.2+
- Python 3 and
pipavailable on the server (or in the Docker container) - Apache with
mod_rewriteor Nginx - A public sitemap (WordPress core generates
/wp-sitemap.xmlautomatically)
Installation
From WordPress admin (ZIP upload)
- Download the latest
wp-static-python.zipfrom the Releases page (or clone this repo and zip thewp-static-pythonfolder). - In WordPress, go to Plugins → Add New → Upload Plugin.
- Choose the ZIP file and click Install Now.
- Click Activate Plugin.
If you download the source ZIP directly from GitHub (green "Code → Download ZIP"), WordPress can still install it. If the extracted folder name differs (e.g.
wp-static-python-main), simply rename it towp-static-pythonafter extraction, or use a release ZIP.
Manual (FTP / SSH)
- Upload the
wp-static-pythonfolder towp-content/plugins/. - Activate the plugin through the Plugins menu in WordPress.
Usage
-
Navigate to the WP Static menu in the admin sidebar.
-
Confirm the detected Sitemap URL (modify if needed).
-
Check Force refresh only if you want to overwrite previously generated static files (adds the
-fflag). -
Copy and run the three SSH commands one by one in your server terminal:
cd /path/to/wordpress python3 -m pip install -r ./wp-content/plugins/wp-static-python/python/wpstatic/requirements.txt python3 ./wp-content/plugins/wp-static-python/python/wpstatic/wpstatic.py 'https://yoursite.com/sitemap.xml' ./static/ -
Configure your web server using the snippets shown on the admin page (also documented below).
-
Visit your site — static HTML is now served first.
Web Server Configuration
Apache (.htaccess)
Add the following block before the default # BEGIN WordPress section in your WordPress root .htaccess:
# BEGIN WP Static Python - static first
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^$ /static/index.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/static/$1/index.html -f
RewriteRule ^(.+?)/?$ /static/$1/index.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/static/$1.html -f
RewriteRule ^(.+?)/?$ /static/$1.html [L]
</IfModule>
# END WP Static Python
# BEGIN WordPress
# ... default WordPress rules remain unchanged ...
# END WordPress
Nginx
Merge the try_files directive into your existing location / block inside the server block:
# Static first: look in /static, then fall back to WordPress
location / {
try_files /static/$uri /static/$uri/ /static/$uri.html /static/$uri/index.html
$uri $uri/ /index.php?$args;
}
# Keep your existing PHP handler, e.g.
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock; # adjust PHP version
}
Test and reload:
sudo nginx -t && sudo systemctl reload nginx
How It Works
For a request such as /about/:
- The web server first checks
static/about/index.html. - If the file exists, it is returned directly — no PHP or MySQL overhead.
- If it does not exist, the request falls through to WordPress'
index.php, which renders the dynamic page as usual.
After you change content in WordPress, re-run step 3 (the generator command) to refresh the static files. Purge CDN/page cache if applicable.
Python Script Reference
wpstatic.py <sitemap_url> <output_dir> [-f]
- Recursively parses sitemap XML (including sub-sitemaps ending in
.xml) - Downloads the homepage plus every URL found
- Saves each page as
<output_dir>/<path>/index.html -fforces re-download by appending a random query string
Dependencies (requests, lxml) are installed via requirements.txt.
Frequently Asked Questions
Do I need root / sudo?
You only need permission to write to the WordPress root directory (so that static/ can be created). Installing Python packages may require sudo or a virtual environment if your system Python is protected — you can also run the commands inside a virtualenv.
Does it work with Docker?
Yes. Run the commands inside the container (where /var/www/html is the WordPress root), or on the host if the WordPress directory is bind-mounted — the commands use relative paths and work from either location.
What about WooCommerce / logged-in users? This plugin is best suited for mostly-static marketing / content sites. Dynamic pages (cart, checkout, my-account, admin, logged-in sessions) will fall through to WordPress automatically because no static files are generated for them — do not add such URLs to your sitemap.
How do I exclude a page from being static?
Do not include it in your sitemap. You can also use a SEO plugin to set pages to noindex, or simply delete the corresponding folder under static/.
Changelog
1.0.0
- Initial release: sitemap-based static generation, admin dashboard with copy-to-clipboard SSH commands, Apache and Nginx configuration snippets.
License
GPL-2.0-or-later. See LICENSE.
Read the full README on GitHub →
Releases
| Tag | Published | Asset | Downloads |
|---|---|---|---|
| v1.0.0 | Aug 22, 2026 | wp-static-python.zip | 1 |