Wijnand (CEO) and Roger) (CCO) join forces in this advanced webinar on How to use the WPCS CLI and a “Lifecycle Hook” to install, activate, and configure a plugin for all websites at the same time.
In this 50-min webinar, you’ll learn everything you need to know to automate the installation and configuration of plugins using the example of the Yoast plugin. The guys walk you through the steps in real-time and explain important features of WPCS as they move along in the process.
WPCS is the WordPress multi-tenant cloud platform, giving you the ability to manage all your WP sites as one. Using our API, CLI, and unique Versioning System, you only have to develop one WordPress website to manage thousands.
After the webinar, you’ll see that the process never gets more complex. No matter how you grow, WPCS can facilitate your journey to managing thousands of websites while actually managing and developing less.
Overview of the webinar #
Here’s an overview of the webinar, followed by references used in the process.
- Configuring LocalWP
- Adding a health-checker plugin in a local WP install
- Checking if the necessary software is installed for the CLI
- Configuring the CLI with WPCS API credentials
- Pushing local WP with Health Checker install to WPCS Console
- Creating a few tenants to demonstrate how WPCS works
- Adding Yoast to local WP install
- Making some configurations in Yoast in local wp install
- Creating a must-use plugin that includes a lifecycle hook
- Adding code to activate and setup Yoast, based on the configuration from the local wp install
- Pushing the local install to WPCS Console
- Moving tenants to trigger the lifecycle hook that activates and configures Yoast
- Showing results
- Discussing how multi-tenant WordPress solves the limitations of Multisite and how every agency can manage any portfolio in WPCS
The webinar follows 5 simple steps to setup CLI, use the lifecycle hook, and deploy to WPCS:
Step 1: Install the necessary software #
Needed on your computer (all free software):
Step 2: Configure LocalWP #
Needed in LocalWP:
Either:
- A WordPress installation in LocalWP that contains all the plugins and themes that you want to use for your websites (don’t have to be activated)
- An import in LocalWP of an existing website that you want to be pushed to WPCS. Here’s an article on how to import a site in LocalWP.
Step 3: Configure .env file in your local WP install with WPCS API keys #
Open the WP folder of your local install in LocalWP and, using a visual editor such as Visual Code, make a file in the WP folder in Public, where also wp_config is and name it: .wpcs-cli.env
Then, add:
WPCS_DEFAULT_REGION=eu1-or-us1
WPCS_DEFAULT_API_KEY=your-api-key
WPCS_DEFAULT_API_SECRET=your-api-secret
Save the visual editor and open the site shell of the wp install.
Inside the terminal, check if the CLI works:
- Check Node: node -v
- Check WP CLI: wp —version
- npx @wpcs.io/cli check
Step 4: Create mu-plugin (and insert code snippet) #
In LocalWP, open the WP folder of your local install again and, using a visual editor such as Visual Code, make a file in the wp-content folder and name it “mu-plugins”.
Create a plugin with the name “your-plugin-name.php”, we went for “activate-and-configure-yoast.php”.
<?php
/**
* Plugin Name: Activate and Configure Yoast
*/
add_action('wpcs_tenant_moved', 'after_tenant_moved');
function after_tenant_moved() {
$is_yoast_active = is_plugin_active('wordpress-seo/wp-seo.php');
if (!$is_yoast_active) {
activate_plugin('wordpress-seo/wp-seo.php');
update_option('yoast_migrations_free', unserialize('a:1:{s:7:"version";s:4:"18.9";}'));
update_option('wpseo', unserialize('a:57:{s:8:"tracking";b:0;s:22:"license_server_version";b:0;s:15:"ms_defaults_set";b:0;s:40:"ignore_search_engines_discouraged_notice";b:0;s:19:"indexing_first_time";b:0;s:16:"indexing_started";b:0;s:15:"indexing_reason";s:26:"permalink_settings_changed";s:29:"indexables_indexing_completed";b:1;s:7:"version";s:4:"18.9";s:16:"previous_version";s:0:"";s:20:"disableadvanced_meta";b:1;s:30:"enable_headless_rest_endpoints";b:1;s:17:"ryte_indexability";b:1;s:11:"baiduverify";s:0:"";s:12:"googleverify";s:0:"";s:8:"msverify";s:0:"";s:12:"yandexverify";s:0:"";s:9:"site_type";s:0:"";s:20:"has_multiple_authors";s:0:"";s:16:"environment_type";s:0:"";s:23:"content_analysis_active";b:0;s:23:"keyword_analysis_active";b:0;s:21:"enable_admin_bar_menu";b:1;s:26:"enable_cornerstone_content";b:0;s:18:"enable_xml_sitemap";b:1;s:24:"enable_text_link_counter";b:1;s:22:"show_onboarding_notice";b:1;s:18:"first_activated_on";b:0;s:13:"myyoast-oauth";b:0;s:26:"semrush_integration_active";b:1;s:14:"semrush_tokens";a:0:{}s:20:"semrush_country_code";s:2:"us";s:19:"permalink_structure";s:12:"/%postname%/";s:8:"home_url";s:24:"http://webinardemo.local";s:18:"dynamic_permalinks";b:0;s:17:"category_base_url";s:0:"";s:12:"tag_base_url";s:0:"";s:21:"custom_taxonomy_slugs";a:0:{}s:29:"enable_enhanced_slack_sharing";b:1;s:25:"zapier_integration_active";b:0;s:19:"zapier_subscription";a:0:{}s:14:"zapier_api_key";s:0:"";s:23:"enable_metabox_insights";b:0;s:23:"enable_link_suggestions";b:0;s:26:"algolia_integration_active";b:0;s:14:"import_cursors";a:0:{}s:13:"workouts_data";a:1:{s:13:"configuration";a:1:{s:13:"finishedSteps";a:0:{}}}s:28:"configuration_finished_steps";a:0:{}s:36:"dismiss_configuration_workout_notice";b:0;s:19:"importing_completed";a:0:{}s:26:"wincher_integration_active";b:1;s:14:"wincher_tokens";a:0:{}s:36:"wincher_automatically_add_keyphrases";b:0;s:18:"wincher_website_id";s:0:"";s:18:"first_time_install";b:1;s:34:"should_redirect_after_install_free";b:0;s:34:"activation_redirect_timestamp_free";i:1653914747;}'));
update_option('wpseo_titles', unserialize('a:106:{s:17:"forcerewritetitle";b:0;s:9:"separator";s:7:"sc-dash";s:16:"title-home-wpseo";s:42:"%%sitename%% %%page%% %%sep%% %%sitedesc%%";s:18:"title-author-wpseo";s:41:"%%name%%, Author at %%sitename%% %%page%%";s:19:"title-archive-wpseo";s:38:"%%date%% %%page%% %%sep%% %%sitename%%";s:18:"title-search-wpseo";s:63:"You searched for %%searchphrase%% %%page%% %%sep%% %%sitename%%";s:15:"title-404-wpseo";s:35:"Page not found %%sep%% %%sitename%%";s:25:"social-title-author-wpseo";s:8:"%%name%%";s:26:"social-title-archive-wpseo";s:8:"%%date%%";s:31:"social-description-author-wpseo";s:0:"";s:32:"social-description-archive-wpseo";s:0:"";s:29:"social-image-url-author-wpseo";s:0:"";s:30:"social-image-url-archive-wpseo";s:0:"";s:28:"social-image-id-author-wpseo";i:0;s:29:"social-image-id-archive-wpseo";i:0;s:19:"metadesc-home-wpseo";s:0:"";s:21:"metadesc-author-wpseo";s:0:"";s:22:"metadesc-archive-wpseo";s:0:"";s:9:"rssbefore";s:0:"";s:8:"rssafter";s:53:"The post %%POSTLINK%% appeared first on %%BLOGLINK%%.";s:20:"noindex-author-wpseo";b:0;s:28:"noindex-author-noposts-wpseo";b:1;s:21:"noindex-archive-wpseo";b:1;s:14:"disable-author";b:0;s:12:"disable-date";b:0;s:19:"disable-post_format";b:0;s:18:"disable-attachment";b:1;s:20:"breadcrumbs-404crumb";s:25:"Error 404: Page not found";s:29:"breadcrumbs-display-blog-page";b:1;s:20:"breadcrumbs-boldlast";b:0;s:25:"breadcrumbs-archiveprefix";s:12:"Archives for";s:18:"breadcrumbs-enable";b:1;s:16:"breadcrumbs-home";s:4:"Home";s:18:"breadcrumbs-prefix";s:0:"";s:24:"breadcrumbs-searchprefix";s:16:"You searched for";s:15:"breadcrumbs-sep";s:7:"»";s:12:"website_name";s:0:"";s:11:"person_name";s:0:"";s:11:"person_logo";s:0:"";s:22:"alternate_website_name";s:0:"";s:12:"company_logo";s:0:"";s:12:"company_name";s:0:"";s:17:"company_or_person";s:7:"company";s:25:"company_or_person_user_id";b:0;s:17:"stripcategorybase";b:0;s:26:"open_graph_frontpage_title";s:12:"%%sitename%%";s:25:"open_graph_frontpage_desc";s:0:"";s:26:"open_graph_frontpage_image";s:0:"";s:10:"title-post";s:39:"%%title%% %%page%% %%sep%% %%sitename%%";s:13:"metadesc-post";s:0:"";s:12:"noindex-post";b:0;s:23:"display-metabox-pt-post";b:1;s:23:"post_types-post-maintax";i:0;s:21:"schema-page-type-post";s:7:"WebPage";s:24:"schema-article-type-post";s:7:"Article";s:17:"social-title-post";s:9:"%%title%%";s:23:"social-description-post";s:0:"";s:21:"social-image-url-post";s:0:"";s:20:"social-image-id-post";i:0;s:10:"title-page";s:39:"%%title%% %%page%% %%sep%% %%sitename%%";s:13:"metadesc-page";s:0:"";s:12:"noindex-page";b:0;s:23:"display-metabox-pt-page";b:1;s:23:"post_types-page-maintax";i:0;s:21:"schema-page-type-page";s:7:"WebPage";s:24:"schema-article-type-page";s:4:"None";s:17:"social-title-page";s:9:"%%title%%";s:23:"social-description-page";s:0:"";s:21:"social-image-url-page";s:0:"";s:20:"social-image-id-page";i:0;s:16:"title-attachment";s:39:"%%title%% %%page%% %%sep%% %%sitename%%";s:19:"metadesc-attachment";s:0:"";s:18:"noindex-attachment";b:0;s:29:"display-metabox-pt-attachment";b:1;s:29:"post_types-attachment-maintax";i:0;s:27:"schema-page-type-attachment";s:7:"WebPage";s:30:"schema-article-type-attachment";s:4:"None";s:18:"title-tax-category";s:53:"%%term_title%% Archives %%page%% %%sep%% %%sitename%%";s:21:"metadesc-tax-category";s:0:"";s:28:"display-metabox-tax-category";b:1;s:20:"noindex-tax-category";b:0;s:25:"social-title-tax-category";s:23:"%%term_title%% Archives";s:31:"social-description-tax-category";s:0:"";s:29:"social-image-url-tax-category";s:0:"";s:28:"social-image-id-tax-category";i:0;s:18:"title-tax-post_tag";s:53:"%%term_title%% Archives %%page%% %%sep%% %%sitename%%";s:21:"metadesc-tax-post_tag";s:0:"";s:28:"display-metabox-tax-post_tag";b:1;s:20:"noindex-tax-post_tag";b:0;s:25:"social-title-tax-post_tag";s:23:"%%term_title%% Archives";s:31:"social-description-tax-post_tag";s:0:"";s:29:"social-image-url-tax-post_tag";s:0:"";s:28:"social-image-id-tax-post_tag";i:0;s:21:"title-tax-post_format";s:53:"%%term_title%% Archives %%page%% %%sep%% %%sitename%%";s:24:"metadesc-tax-post_format";s:0:"";s:31:"display-metabox-tax-post_format";b:1;s:23:"noindex-tax-post_format";b:1;s:28:"social-title-tax-post_format";s:23:"%%term_title%% Archives";s:34:"social-description-tax-post_format";s:0:"";s:32:"social-image-url-tax-post_format";s:0:"";s:31:"social-image-id-tax-post_format";i:0;s:14:"person_logo_id";i:0;s:15:"company_logo_id";i:0;s:17:"company_logo_meta";b:0;s:16:"person_logo_meta";b:0;s:29:"open_graph_frontpage_image_id";i:0;}'));
update_option('wpseo_social', unserialize('a:19:{s:13:"facebook_site";s:0:"";s:13:"instagram_url";s:0:"";s:12:"linkedin_url";s:0:"";s:11:"myspace_url";s:0:"";s:16:"og_default_image";s:0:"";s:19:"og_default_image_id";s:0:"";s:18:"og_frontpage_title";s:0:"";s:17:"og_frontpage_desc";s:0:"";s:18:"og_frontpage_image";s:0:"";s:21:"og_frontpage_image_id";s:0:"";s:9:"opengraph";b:1;s:13:"pinterest_url";s:0:"";s:15:"pinterestverify";s:0:"";s:7:"twitter";b:1;s:12:"twitter_site";s:0:"";s:17:"twitter_card_type";s:19:"summary_large_image";s:11:"youtube_url";s:0:"";s:13:"wikipedia_url";s:0:"";s:17:"other_social_urls";a:0:{}}'));
}
}
A note about the Lifecycle Hook we used: #
In some cases, it can be very beneficial to run some PHP in your tenants when certain important events happen. For example. it could be important to add some user meta to the newly created user or update some posts when the tenant has been created. To enable this, WPCS supports several WordPress hooks that are called during important lifecycle events. In this webinar, we used this Tenant Lifecycle Hook to trigger the PHP snippet only after a tenant was moved to a new version.
To use these hooks, you can use a PHP snippet plugin or create your own custom plugin that implements these hooks. The choice is yours. In this example, obviously, we used our own must-use plugin. For more information about Lifecycle Hooks:
Step 5: Deploy local WP install to WPCS #
Open the site shell of your local install in LocalWP and check the CLI:
- npx @wpcs.io/cli tenant list (to check if you’re in the right product)
Then deploy your local installation to WPCS:
- npx @wpcs.io/cli local deploy –name [NAME]
- npx @wpcs.io/cli tenant create testcli (if you want to create a tenant instead of a Version)
☝? If at any stage you need help while using the WPCS CLI, just type “npx @wpcs.io/cli help” and explore from there. Have fun!