Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
BSS to WordPress - Automatically Publishes Bootstrap Studio Exports to WordPress
/* This script automatically publishes BSS exports to WordPress.
* Install Composer from . Composer needs to be installed on your local computer where BSS is installed, NOT on the server.
* Use Composer to install QueryPath (also on your local computer), following the instructions at
* On the server, install the JSON Basic Authentication WordPress plugin from
* Create an ini file in the bss_exports parent directory, containing values for base_url, wp_username, wp_password.
* BSS automatically creates an assets folder in the export directory. This folder contains subfolders for css, images, js, etc... To automatically upload assets, provide ini values for ssh_username, ssh_host, ssh_path (file system path to your public web directory with no trailing slash)
* In BSS, create a meta tag for each page you want to publish. <meta name="id" content="POST_ID" /> QP is CASE SENSITIVE, so you must use "id", NOT "ID". Replace POST_ID with the Post ID of the WordPress page. You can obtain this by editing the page in WordPress and viewing the ID in the URL.
* The pages must already exist in WordPress before they can be updated by this script.
* Configure BSS to run this script on export. BSS will automatically pass the path of the exported files as a parameter to this script.
* For each exported page, the script will publish the content of body > div.container or body > div.container-fluid. Make sure the structure of the BSS page conforms to this structure, with the container div immediately following the body tag.
* Apache does not allow Basic Authentication by default and will thrown 403 errors. To enable Basic Authenticaiton, add the following line to the .htaccess file in your WordPress web directory:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
You'll need to enable display of hidden files to make .htaccess visible so you can edit it.
* If the script doesn't work, try running it from the command line. If you get a PHP "bad interpreter" error, it means some illegal character is interfering with the shebang, possibly a Windows CR/LF. Run the script through dos2unix (installed via brew) and make sure the permissions are 755.
require 'vendor/autoload.php';
if (empty($argv[1])) {
echo "Export path not specified. Aborting!\n";
$path = $argv[1];
$params = parse_ini_file("$path/../bss_to_wordpress.ini"); // ini file should be saved in the parent directory of bss_exports
$files = scandir($path);
foreach ($files as $file) {
if (substr($file, -5) == '.html') {
$qp = html5qp("$path/$file");
if ($id = $qp->find("meta[name='id']")->attr('content')) { // Get the Post ID stored in the meta id tag. QP is CASE SENSITIVE, so you must use "id", NOT "ID"
$content = str_replace('="assets', '="/assets', $qp->find("body > div.container, body > div.container-fluid")->html5()); // Extract the main container content and replace relative references to the assets folder with absolute references
$data = json_encode(['content' => $content]);
$ch = curl_init($params['base_url'] . "/wp-json/wp/v2/pages/$id");
curl_setopt($ch, CURLOPT_USERPWD, curl_escape($ch, $params['wp_username']) . ":" . $params['wp_password']);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
$response = curl_exec($ch);
shell_exec("rsync -av --delete --size-only '$path/assets' " . $params['ssh_username'] . '@' . $params['ssh_host'] . ':' . $params['ssh_path']); // Sync assets based on size only, deleting any files that don't exist locally
shell_exec("rm -rf '$path/assets/'"); // Delete the assets directory structure, so the next export will be clean
Copy link

harimau99 commented Apr 22, 2018

Hi Bkonia, i have come across your post few days ago ..
To understand this, i dig out the conversation at BSS. However, i still don't get it how it is implement in WP?

hope to hear from you soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment