Asynchronous publishing actions on VIP Go

Often when a post is published, there’s a number of actions associated with that publication. Some of those actions can take a while to perform, for example syndicating content out to sibling sites, pushing to social media, etc.

On VIP Go you can easily offload actions to be processed asynchronously on the Cron infrastructure for your site when a post is published or transitions status. Offloading actions reduces the processing time required for your publish action, which makes for a much faster and nicer publishing experience for your editors.

How to offload actions

Offloading an action on publish for asynchronous processing is as simple as changing the publish action hook to one of our async_ equivalents. The hooks we have available for asynchronous processing are:

  • async_transition_post_status, the asynchronous equivalent of transition_post_status (core hook docs)
  • async_{$old_status}_to_{$new_status}, the asynchronous equivalent of {$old_status}_to_{$new_status} (core hook docs)
  • async_{$new_status}_{$post->post_type}, the asynchronous equivalent of {$new_status}_{$post->post_type} (core hook docs)

This hypothetical code example splits off some functionality to be processed as the post is published, and some longer running functionality to be processed asynchronously:

/**
 * Runs when a post of type `post` is published.
 */
function my_post_publish_actions() {
	// This function performs quick actions,
	// and things which must happen immediately
}
add_action( 'publish_post', 'my_post_publish_actions' );

/**
 * Runs asynchronously, when a post of type `post` is published.
 */
function my_slower_post_publish_actions() {
	// This function performs slower actions,
	// like syndication and other longer 
	// running tasks
}
add_action( 'async_publish_post', 'my_slower_post_publish_actions' );

The code which powers our asynchronous offloading functionality works by scheduling an immediate Cron event to be processed on our dedicated Cron infrastructure, during which these async_* action hooks are called.

Caveats

The asynchronous actions will be processed on separate infrastructure to the web requests; this means that the asynchronous action will not have access to anything which has been placed in the global context, or access files placed in the System temp directory, etc.

Setting Up the Ads.txt File

What is ads.txt?

It’s an IAB-approved text file to prevent unauthorized sales of inventory.  You can read more about it on their website: https://iabtechlab.com/ads-txt/

Setting It Up

Since requirements specify that the /ads.txt file must be located in the root domain, we highly recommend to place the ads.txt file in your theme and then, create a rewrite rule for the URL. Here is an example for WordPress.com VIP platform:

// TODO: change `my_theme` prefix to my theme's prefix!
/**
 * Register the rewrite rule for /ads.txt request.
 */
function my_theme_adstxt_rewrite() {
	add_rewrite_rule( '^ads\.txt$', 'index.php?my_theme_adstxt=true', 'top' );
}
add_action( 'init', 'my_theme_adstxt_rewrite', 10 );

/**
 * Filter the list of public query vars in order to allow the WP::parse_request
 * to register the query variable.
 *
 * @param array $public_query_vars The array of whitelisted query variables.
 *
 * @return array
 */
function my_theme_adstxt_query_var( $public_query_vars ) {
	$public_query_vars[] = 'my_theme_adstxt';
	return $public_query_vars;
}
add_filter( 'query_vars', 'my_theme_adstxt_query_var', 10, 1 );

/**
 * Hook the parse_request action and serve the ads.txt when custom query variable is set to 'true'.
 *
 * @param WP $wp Current WordPress environment instance
 */
function my_theme_adstxt_request( $wp ) {
	if ( isset( $wp->query_vars['my_theme_adstxt'] ) && 'true' === $wp->query_vars['my_theme_adstxt'] ) {
		/*
		 * Set proper content-type per specification in
		 * https://iabtechlab.com/wp-content/uploads/2017/09/IABOpenRTB_Ads.txt_Public_Spec_V1-0-1.pdf :
		 *
		 * The HTTP Content-type should be ‘text/plain’, and all other Content-types should be treated
		 * as an error and the content ignored.
		 */
		header( 'Content-Type: text/plain' );

		// The code expects an existing ads.txt file in the root of your active theme.
		echo file_get_contents( get_stylesheet_directory() . '/ads.txt' );
		exit;
	}
}
add_action( 'parse_request', 'my_theme_adstxt_request', 10, 1 );

On WordPress.com, there should be no need to flush your rewrite rules, as it happens automatically upon deploy. For VIP Go, and in cases where the redirect does not working as expected, please head to VIP => Rewrite Rules and hit the “Flush Rewrite Rules” button.

Note: this is just one way to go about doing so; if there is another way that works better for your theme, feel free to employ it!

If you’d like to be able to modify and validate your ads.txt file from the admin interface, the Ads.txt Manager plugin from VIP Featured Partner 10up allows you to do so, and is approved for use on both WordPress.com VIP and VIP Go.

Restricting access to a site hosted on VIP Go

Many VIP Go clients have the requirement to control access to their site so only a specific group of users are able to access it. For launched production sites, your solution must be architected around anonymous users and authenticated users:

Anonymous users can be served with a login screen, a page with information on how to authenticate, or a simple denial notice, etc. This response should be served with an HTTP Status of 200, and you may choose to include information about how a user can authenticate to access the site fully. This response will be cached by the VIP Go page cache.

Authorized users must log in using a WordPress user account, and you can tailor the output to these users, vary the content for different users, etc. Logged in users bypass VIP Go page caching. If your organization has a Single Sign On system, then integrating this with your VIP Go site will smooth the log in experience for your users (see “Single Sign On (SSO)” below).

Requirements and Notes

Single Sign On (SSO)

Single Sign On systems provide a central log in system for all of your company’s services, they simplify life for your users by removing the need to configure separate usernames and passwords for each system each user needs to use. VIP Go allows integration with SSO systems to simplify authentication.

Your SSO integration must create local WordPress user accounts and use standard WordPress authentication cookies, in order to work correctly on the VIP Go platform. These accounts can be restricted such that they cannot user passwords to sign in and are required to authenticate via your SSO flow instead.

The VIP Support team will require access to your site, so you must allow users from inside our network to bypass your SSO integration and log in as usual with a username and password. Requests from inside our authenticated network can be identified by checking that the A8C_PROXIED_REQUEST constant is true (see “Checking for requests from inside Automattic’s network” below). If you have any questions about this, please contact us and we’ll be happy to help.

The WordPress REST API

Your site content can be accessed via the WordPress REST API, so if you need to constrain access to site content then your solution must take this into account.

As many VIP Go features utilise the WordPress REST API, we do not allow sites to disable this API completely. If you need to restrict access to your site via the WordPress REST API, you should force authentication for API endpoints.

Whitelisting access by IP address

If you need to restrict the display of certain content to authorized users, then those users must be logged in, this is to ensure that responses to these users are not cached. During the log in process (and on every subsequent request) you can hook into WordPress to reject the log in if the user is not on an authorized IP address.

In order for the VIP team to support your site our users must still be able to log in to your site, despite not being on your IP whitelist. Requests from inside our authenticated network can be identified by checking that the A8C_PROXIED_REQUEST constant is true (see “Checking for requests from inside Automattic’s network” below).

You must not add IP address restrictions for anonymous users in PHP code, and it is not possible for us to configure your site to restrict access to a limited range of IP addresses in our web server or caching layers. Implementing IP restrictions in PHP code will cause issues within the cached responses to your site; consider the following scenario:

  1. User A visits page 1, this user is from an “authorized IP address”
  2. The VIP Go site serves a tailored response to User A, showing them content only available to certain specific users
  3. The VIP Go page cache caches the response
  4. User B visits page 2, this user is not from an “authorized IP address”
  5. The VIP Go page cache responds to User B with the cached information, i.e. the content which was served to User A, content which was only intended to be available tocertain specific users

Restricting access to user uploaded files

Files which are uploaded to your VIP Go site media library are served by the VIP Go Files Service. It is not possible to control access to your uploaded files via authentication; i.e. it is not possible to restrict access to a file to logged in users only, nor to users from particular IP addresses.

You must not block xmlrpc.php

Various VIP Go platform services use the /xmlrpc.php endpoint, so this must not be blocked by any access restrictions you put into place. Access to the /xmlrpc.php endpoint is restricted to authorised requests only, so additional constraints are not necessary.

Checking for requests from inside Automattic’s network

The following code example shows how to check that the request is from a user inside Automattic’s network.

if ( defined( 'A8C_PROXIED_REQUEST' ) && true === A8C_PROXIED_REQUEST ) {
    // The request originates from WordPress.com VIP (Automattic)
}

Can I mark some entries as “no cache” to avoid issues with caching?

Anonymous user requests should always be cached, and you must not send “no cache” headers to anonymous users. If you want to show the user restricted content and not have this content cached the user should be logged in, logged in users bypass the VIP Go .

Is there a scaling issue with so many uncached users browsing my site?

Your site can scale to handle many thousands of logged in users with the help of our standard VIP Go guidelines for scaling websites. We are happy to talk through your particular use cases, please get in touch.

Basic Authentication for un-launched sites

Basic Authentication is the “pop up” prompt for a username and password which is displayed by your browser when you visit a site which is protected in this way.

While a site is under development, and for non-production sites, we can set up Basic Authentication for you. If you’d like us to do this, please contact us and we’ll be happy to do so.

It is not possible for launched production sites to use Basic Authentication, as this form of access control breaks various VIP Go platform services.

Maintenance Mode

While a site is under development, you can also use the Maintenance Mode plugin to restrict access to your site. Add this plugin to your site by following the instructions for enabling plugins on VIP Go and configuring Maintenance Mode.

Setting up your Development Environment

Like all software development, you should develop and test your code in your local development environment before committing the code to WordPress.com VIP. This document will help you set up an environment to aid development of your WordPress.com VIP hosted site.

Please note: This document relates to the WordPress.com VIP platform. VIP Go related documentation can be found here.

Caveats

WordPress.com is a large web application that has been developed over the past 10+ years. Please note that the environment setup described here will not provide a 1:1 copy of your production environment. While we’ve tried to bridge various gaps, many features are very challenging to reproduce locally and environmental differences will exist. A non-exhaustive list of these differences can be found here.

We’re also happy to help guide and assist you with any concerns/issues you have with these differences.

Getting Started

  1. Install a local Multisite WordPress environment. We recommend Chassis or VVV.
    • Use Chassis if you want an environment that’s simple yet powerful. It’s a minimalist development setup that boots up fast and gets out of the way.
    • Use VVV if you want an environment that comes with lots of features, is highly extensible, and can run many different site configurations.
    • You can also roll your own setup (like something built on Docker).

    Note: Your environment should be be set up as a Multisite (Chassis has a config flag; VVV requires a custom site template; and custom setups can follow the Codex).

  2. Install VIP Plugins and Helpers to wp-content/themes/vip/plugins:
    svn co https://vip-svn.wordpress.com/plugins/ wp-content/themes/vip/plugins
    

    You should svn up daily to ensure you’re working with the latest code.

  3. Install VIP mu-plugins to wp-content/mu-plugins:
    git clone --recursive https://github.com/automattic/vip-wpcom-mu-plugins wp-content/mu-plugins
    

    You should git pull daily as well to ensure you’re working with the latest code.

    The readme covers other environment-specific things like concatenation and caching that you may want to set up as well.

  4. Install your theme to wp-content/themes/vip/{your-theme}. If you’re just starting out with VIP, please read through Anatomy of a VIP Theme to get an overview of what your theme should look like.

wp-content

When set up correctly, your wp-content directory should likely look something like:

wp-content/
    plugins/
    mu-plugins/
        0-local.php
        ...
    themes/
        vip/
            your-theme/
                plugins/
                    your-custom-plugin/
                        your-custom-plugin.php
                        ...
                functions.php
                style.css
                ...
            plugins/
                vip-init.php
                ...    

The Stack

As of March 30, 2018, we are using the following pieces of software across our stack:

  • Debian Stable
  • PHP 7.2
  • MariaDB 10.2
  • NGINX (latest)
  • Memcached (latest)

Note that the one most likely to impact your day-to-day work is the PHP version.

WordPress Updates

We are usually running the latest stable release of WordPress core on WordPress.com.

We try to provide adequate notice for releases of major versions on the platform. When a pending release is announced, we recommend switching over your local environment to use the beta tester plugin or a SVN checkout of trunk to make sure you’re running the latest version and can test for any issues before they are rolled out.

Your Content

You can use the built-in export/import functionality in WordPress to populate your local environment with test data. You can generate an export from your site’s Dashboard and then use either wp-cli or the Dashboard Importer to import the content. If you have issues exporting or importing, please get in touch and we’d be happy to help.

If you are just starting out and need some data to play with, check out the demo files that the Automattic Theme Team uses for building and testing new themes.

You can also use WP Options Importer to export/import options (like widgets, plugin settings, etc.).

Debugging

You should always have debugging enabled in your local environment help catch errors as you develop:

// In your wp-config.php
define( 'WP_DEBUG', true );
define( 'SAVEQUERIES', true );

// Optional
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', true );

// Learn more: https://developer.wordpress.org/themes/getting-started/setting-up-a-development-environment/#wp_debug

Development Tools

We also recommend the following plugins and tools:

Note that these tools are meant for development/debugging only and should not be included in your theme or pushed to production.

Staging Environments

For staging environments, the only difference would be to use a hosting provider of your choice for your WordPress environment (some examples include DigitalOcean, AWS, and so on).

Commit and Deploy Webhooks

As well as receiving e-mail notifications, you can set up repository-specific commit and deploy webhooks for your WordPress.com VIP code.

Set up

To tell WordPress.com which webhooks to ping, simply add a wpcom-meta.php to the root of your repo with something like this;


<?php
/**
 * Commit Webhook: https://incoming.my-webhook.com/commit
 * Deploy Webhook: https://incoming.my-webhook.com/deploy
 */

Committing that file is all you need to do to create the webhooks. If you have any difficulties, or need more information, don’t hesitate to open a ticket with us.

Note: Services, such as Slack, require data to be transformed into a standard format for their platform. So in this instance you would have to transform the data prior to passing it to Slack.

Commit Webhook

The commit webhook will provide the following data:

  • repo – The name of the repository.
  • theme – The name of the theme.
  • revision – The committed revision number.
  • committer – The WordPress.com username of the committer.

Deploy Webhook

The deploy webhook will provide the following data:

  • repo – The name of the repository.
  • theme – The name of the theme.
  • previous_revision – The previously deployed revision.
  • deployed_revision – The deployed revision number.
  • deployer – WordPress.com username of the person who deployed the revision.
  • revision_log – A log of commits between the previously deployed and newly deployed revisions.

Personalization

As the audience of your website grows, it becomes more challenging to publish content that is relevant to all readers. Personalization gives you the ability to profile each user’s behavior and capture their preferences, allowing you to display more relevant content and ultimately, keep your audience engaged.

What is personalization?

Personalization can mean different things to different people but it mainly involves providing your audience with a more customized and engaging experience. It could mean that you’re providing content that is more relevant to their geographic location or that you’re providing them more relevant content based on what they’ve viewed or liked in the past. Personalization could also mean that your users are able to share content with each other and follow people or topics that they are interested in.

Considerations

Before diving into using the most popular plugins for personalization, there are a few items that you would want to keep in mind, regardless of the type of personalization that you’re interested in. 

  • Sending data to the personalization vendor: If the personalization requires you to send them any data (user data, activity data, etc.),  you will have to include a javascript snippet in all of your pages. Be sure to choose a reliable third party vendor as slow response times on their end could affect your end-user experience.
  • Serving recommendations from the personalization vendor: As the recommendations for a specific type of user may change, the recommended list of content is typically sent dynamically from the personalization vendor’s systems. Some vendors store the user’s behavior in a cookie so that your users don’t have to rely on their service being online but make sure you understand what features of your site (if any) will be impacted if the service vendor’s systems go offline.
  • Limiting the user information that is shared: If you require users to sign in with their account, you have the added advantage of using their historical preferences to personalize. However, this would require you to share additional information with the personalization vendor. It is best to let your personalization vendor know just the username or a separate unique identifier for the user.
  • Supporting cross-channel interactions: If you want the flexibility to capture data from your users across various channels (social media, email, mobile apps, website, etc.), you will need a vendor that can unify data from all of these channels to a single user profile (typically based on the email address). Most personalization vendors that support cross-channel data gathering will also let you publish your recommendations through any of these channels.

Types of personalization

There are no limits to how you can personalize your content but the most popular options include:

Customer Identity & Access Management

Personalizations rely heavily on understanding who your customers are. A sophisticated customer identity and access management solution will help you identify your customers regardless of the device or channel they’re engaging from, allowing you to keep your message consistent across a diverse platform.

Janrain, a Featured Partner of VIP, provides a platform that combines your ability to acquire users across multiple digital and marketing channels. In addition to providing a Single Sign-On solution, they provide a hosted user database and provide integration for social sharing.

We have also had VIP clients use Gigya, another popular platform to securely manage and update user profiles, thereby giving you a great starting point to provide personal experiences.

Custom Social Network

If you have built a community, you may be looking to empower your users to share stories, like each other’s’ contributions and have a newsfeed of updates from the people or things that they follow.

The popular BuddyPress plugin built by the WordPress community provides a lot of social network features out of the box. It provides both private messaging and public sharing. However, the vision of some of our clients were better met by using a Featured Partner for custom development.

Predictive Marketing

You might have noticed that some sites have a ‘You might also like’ section, listing content related to what you have been reading. There is another variant of this personalization where content related to the current page is listed. These dynamically shortlisted links are more relevant to your users and have a higher click-through rate.

One of our featured partners: Sailthru, is the leading provider of personalized marketing communications. Their WordPress plugin makes it easy to provide personalized content through their Scout and Concierge modules. Scout provides content relevant to a page whereas Concierge provides content that is recommended for the specific user. Under the covers, both modules use predictive marketing algorithms to determine the best recommendations for your users.  We have had multiple VIP clients use Sailthru’s straightforward integration to personalize their content.

If you’re looking to add a simple ‘Related Posts’ section to your website, WordPress.com’s Related Posts feature may be all you need. It’s powered by the popular Jetpack addon, which uses Elasticsearch to analyze your content and understand its relevance to the rest of your website. You can finetune how the recommendations are displayed using the customization options.

Geo-specific content

As your audience grows, you might find it challenging to provide content that is engaging to your users regardless of where they’re from. WP.com Geo Uniques allows you to target distinct geographic markets with different content. You also have the option of defining custom location groups so that you can target groups smaller than countries.

Uploading video files

Your WordPress.com VIP site’s Media Library can be configured to accept video file types like these:

  • .mp4, .m4v (MPEG-4)
  • .mov (QuickTime)
  • .wmv (Windows Media Video)
  • .avi
  • .mpg
  • .ogv (Ogg)
  • .3gp (3GPP)
  • .3g2 (3GPP2)

To enable these file types on a VIP site, please open a support ticket.

Site Merges

As part of a migration either to WordPress.com VIP or between two WordPress.com VIP sites, you might need to perform a site merge. Doing so is potentially time-consuming and can produce issues that do not normally occur during a site migration.

What Is a Site Merge?

A site merge is any time you are migrating more than one WordPress site’s content into a single WordPress site. This could be:

  • Two (or more) sites you are intending to collapse into one new site in the course of a migration to WordPress.com VIP
  • One site on WordPress.com VIP you are closing and “folding” that content into a parent site on WordPress.com VIP

If you are migrating content and the sources come from more than one posts table, it’s a site merge.

What Makes Site Merges Different from Other Imports?

When you merge more than one WordPress site into a new or existing single site, you will almost definitely encounter post ID overlap in the two datasets. When the WordPress importer then pulls this data into the eventual target site, the post IDs will be necessarily changed as you cannot have more than one post with the same ID.

Because of this, any connections between posts or solutions that have been created to use post IDs as linking data will need to have that data reassigned or rewritten. Anything that uses post IDs will need to take this into consideration, including:

  • Parent/child relationships between posts
  • Featured image assignments for posts
  • Serialized post ID data stored in postmeta
  • Any post ID information used in shortcodes (e.g. the gallery shortcode)

While post IDs are usually the primary concern, this ID confusion can also apply to IDs in other tables, such as term and meta IDs.

Considerations

Compared to an import that is single-site to single-site, you’ll have additional things to consider before the import begins and as you create your timeline for the migration. Keep these things in mind as you work with the WordPress.com VIP team to create achievable and realistic target dates and expectations. Our advice is to keep things as simple as possible. The more complicated your merge, the more time you’ll need for troubleshooting and QA.

Timeline

  • What is your migration timeline?
    • Are you properly allotting enough time to both implement and QA post ID changes that might be necessary due to the merge?
  • How many posts and images are you importing overall?
    • The greater the number of changes, the longer the additional work for a merge will take to complete.
  • Where will you be staging your content? For WordPress.com VIP, it needs to be publicly accessible for us to download images.

Authors

  • Are you using Co-Authors-Plus on one or both sites?
  • Have you looked at author slugs and profiles between the two sites to see how much (if any) overlap you will have?
    • You may need to do bulk reassignment of guest author terms to unify the two sets of guest author profiles and attributions.
  • If you are merging from a site without Co-Authors-Plus to a site using it (or vice versa), how are you going to integrate that data and make sure your authorship attribution is properly carried forward?

Post Relationships and Custom Features

  • Are you utilizing any custom metadata relationships between posts that would encounter trouble if those post IDs were to change?
    • A good example of this is custom photo gallery implementations or even the built-in WordPress galleries feature, which depends on post IDs.
  • You will need a scripting plan to alter the post metadata as needed to match the new post ID assignments. Remember that you can use the _original_post_id meta key to determine which posts have changed and their original IDs.

Publishing Schedules and Site Activity

  • With what frequency are posts created on both sites? This will determine the merge timing and how much data will need to be brought forward using a large initial import followed by smaller delta imports. Content fixing will need to be done at each step and will change the timing available. It’s usually best to move as much as possible in the first migrations and then delta-import smaller chunks of content immediately prior to launch.

Quality Assurance

  • Migrations that involve merges will need additional time and effort dedicated to QA. Because these relationships can be altered, you’ll need to come up with a plan for determining a representative sample of posts or other content to check for consistency. It’s best to do this with the initial large import prior to launch to discover and flag and fix any potential data issues.

Who Should Perform the Merge, and When?

Site merges can and will be performed in different ways depending on the combination of source sites and target sites. Depending on the requirements of the site, it may make more sense for you to perform the merge before the site is moved to WordPress.com VIP at all.

The merge should happen completely prior to moving to WordPress.com VIP if:

  • You are merging more than one site to WordPress.com VIP and the merge can be completed prior to your launch on WordPress.com VIP, or
  • You are merging more than one site that is no longer active into a site that is also no longer active, whether it is on WordPress.com VIP already or not.

The merge should happen entirely on WordPress.com VIP if:

  • You are merging any site into a site that is already live on WordPress.com VIP.

There may be situations where a combination of the two situations is best. Please discuss the merge process with WordPress.com VIP Support for more details.

Starting the Site Merge Process

As with any import to WordPress.com VIP, please contact WordPress.com VIP Support as much in advance as possible so we are aware of and can schedule resources to assist you with the merge process. Make sure you inform us that the import is going to have merged content.

We request that you prepare a local development environment on which you can partially test the merge to look for potential problems and identify scripting needs you’ll need to address. We’ll happily provide you with partial exports for the sites you plan to merge so you can do a test run and identify problems before they occur during an actual import. Remember that imports to a live site are much more difficult to reverse; the more we can help you identify problems ahead of time, the more efficiently and error-free the eventual import and merge will be.

Making Site Merges Successful

We’ll need you and your developers to contribute code for many types of merges, usually in the form of wp-cli commands. When you contact us, we’ll send you a questionnaire to make sure we’re considering all of the factors necessary to ensure your merge is successful.

When you merge to a site on WordPress.com VIP, we’ll take care of:

  • Fixing featured images,
  • Remapping image URLs in post content,
  • Providing useful import origin meta to help you in fixing problems after the fact,
  • Fixing post parent/child relationships, and
  • Fixing duplicate Guest Authors in Co-Authors Plus that might have been created.

You and your development team will need to:

  • Identify any postmeta or shortcode usages in your site content that will be disrupted by a site merge,
  • Create and test any CLI scripts that will be needed to repair these relationships,
  • Commit any needed CLI scripts to your theme, inform us of them and their purpose, and provide us with instructions for executing them at the proper time,
  • Create any scripts needed for term mapping (or perform that prior to the import itself), and
  • Test any merges with sample data to identify potential issues prior to scheduling the site merge import(s).

If you have any questions, please don’t hesitate to contact WordPress.com VIP Support.

VIP Go Local Development

Because developing sites for VIP Go is different than developing for WordPress.com hosted VIP sites, you need a different development environment.

Your VIP Go site runs three codebases: WordPress core (tracking the most current version), the VIP Go mu-plugins, and the codebase from your specific site repo. Because of this, a variety of WordPress local development environments can be suitably configured for VIP Go development purposes.

Here we describe using a VVV-based local development environment. Other options may include: Chassis, Docker-WordPress, Laravel Valet, etc.

VVV for VIP Go Development

Note: These instructions assume a familiarity with command line tools an macOS, Linux, or similar Operating System.

Prerequisite: all git operations referenced in this guide assume you have an ssh keypair registered with GitHub and are using ssh (vs. https) protocols. Using https protocols may lead to unexpected errors and is not supported.

Step 1: Setting up VVV

The basic instructions for installing VVV are in their documentation. Complete setup per their instructions before continuing below.

Step 2: Add your site code

Follow the instructions to add a new site here, and reprovision. Then, find and remove the entire wp-content folder at {VVV FOLDER}/www/{site name}/public_html/wp-content. Replace {VVV FOLDER} with the path to your VVV folder (i.e. the folder you installed VVV into), and {site name} with the name of your site.

Git clone your VIP Go site repo in place of it, using the following command. Replace {CLONE URL} with the GitHub clone URL for your VIP Go GitHub repository.

git clone {CLONE URL} {VVV FOLDER}/www/wordpress-default/public_html/wp-content

Note: VIP Go sites must use the wp-content folder structure from https://github.com/automattic/vip-skeleton. If you do not yet have a VIP Go site repo hosted with us, please use this vip-skeleton repo for the “CLONE URL” above and place your codebase (theme & plugins) within it for testing. Once your VIP Go site repo has been provisioned, you’ll most likely use that repo instead.

Step 3: Add the VIP Go MU plugins

Git clone the VIP Go MU plugins repo at wp-content/mu-plugins/; using the following command. Replace {VVV FOLDER} with the path to your VVV folder (i.e. the folder you installed VVV into).

git clone git@github.com:Automattic/vip-go-mu-plugins.git --recursive {VVV FOLDER}/www/wordpress-default/public_html/wp-content/mu-plugins/

Note: the vip-go-mu-plugins repository is using SSH protocol for submodules, and as GitHub does not allow anonymous SSH connections, you’ll have to set up SSH key for your GitHub account and use it for interaction with the repository (cloning and submodule updates).

Periodically pull changes down from this repository to ensure you have the latest code… we suggest checking for and pulling changes before the start of development on any given day:

$ cd {VVV FOLDER}/www/wordpress-default/public_html/wp-content/mu-plugins/
$ git pull origin master
$ git submodule update --init --recursive

Note: Do not commit the mu-plugins/ directory to your VIP Go site’s repository.

Step 4: Include the VIP config file

Add the following code to your wp-config.php just above this line: /* That's all, stop editing! Happy blogging. */:

if ( file_exists( __DIR__ . '/wp-content/vip-config/vip-config.php' ) ) {
    require_once( __DIR__ . '/wp-content/vip-config/vip-config.php' );
}

That’s it! Your development environment is ready to “Go” and you should see a “VIP” menu in wp-admin.

Disabling unused features and assets

WordPress.com comes with a bunch of useful features turned on by default, and most VIP sites make use of them every day. We also know that sites may want to disable some of these for various reasons, e.g. if you’re focused on performance and minimizing the number of assets loaded, you may want to disable any CSS/JS that would be loaded for features not in use.

We offer a number of helper functions to facilitate this:

  • wpcom_vip_disable_custom_customizer – disables the WordPress.com-specific Customizer and Custom Design
  • wpcom_vip_disable_devicepx_js – devicepx.js loads retina/HiDPI versions of certain files (Gravatars, etc) for devices that run at a higher resolution (such as smartphones). Using this function disables it.
  • wpcom_vip_disable_global_terms – remove your taxonomy from the global taxonomy array
  • wpcom_vip_disable_hovercards – if you are not using Gravatars and Blavatars and need to disable the loading of related Javascript and CSS resources
  • wpcom_vip_disable_likes – disables Likes for Posts and Custom Post Types. Sharing can also be disabled from the Dashboard (Settings > Sharing).
  • wpcom_vip_remove_opensearch – disables rendering of the OpenSearch description documents at /osd.xml and /opensearch.xml
  • wpcom_vip_disable_sharing – disables Sharing in Posts and Pages
  • wpcom_vip_disable_sharing_resources – disables the CSS/JS involved in Sharing functions, powering things like smart buttons and share counts displayed alongside the buttons.
  • wpcom_vip_remove_playlist_styles – disables enqueuing of wp-mediaelement.css which is necessary for sites using Playlist shortcode
  • wpcom_vip_remove_mp6_styles – disables enqueuing f mp6-hacks.css stylesheet which adds backward compatibility for legacy .mp6 body classes
  • wpcom_vip_load_geolocation_styles_only_when_needed – Conditionally dequeues Geo Location stylesheets in case they are not needed. IE.: post is not actually using Geo Location
  • wpcom_vip_remove_bbpress2_staff_css – disables enqueueing of wpcom-bbpress-premium-themes.css stylesheet

Check out all of the helper functions available.

Ready to get started?

Drop us a note.

No matter where you are in the planning process, we’re happy to help, and we’re actual humans here on the other side of the form. 👋 We’re here to discuss your challenges and plans, evaluate your existing resources or a potential partner, or even make some initial recommendations. And, of course, we’re here to help any time you’re in the market for some robust WordPress awesomeness.