Domain Mapping in WordPress Multisite

Domain Mapping in WordPress Multisite

Domain Mapping in WordPress Multisite
A WordPress Multisite installation, as known, allows you to create and manage a network of subsites in a centralized way: each subsite is independent from the others but is still managed as a WordPress site, always within the main installation.
Up to WordPress 4.5, through an additional plugin it was possible to associate a top level domain to each subsite: this feature is called Domain Mapping.
Starting from version 4.5 Domain Mapping has been integrated into WordPress, so it is now a native feature and an external plugin is no longer needed.
Let』s check in the next sections how to set Domain Mapping in a WordPress Multisite.

Table of Contents

WordPress MultisiteDomain Mapping: the roadmapDNS SystemDNS ConfigurationAdd Domain to HostingMap Domain to subsiteInstall SSL Certificate
1. WordPress Multisite
The first step to perform, of course, is to create a Multisite Network. This means to install WordPress as Multisite, and not as Single site. More info on that topic are available here: How to install and set up a WordPress Multisite .
Also, for an overview on the Multisite environment, you can consider this tutorial: The WordPress Multisite Overview with Examples .
Within a Multisite installation you will be able to create as many subsites as you need: each of them will share the same database, and some dedicated tables will be created each time a new subsite is created.
If you want to dig more into technical database details you can refer to WordPress Multisite database tables explained.
Besides, during the installation, and only in that moment, you will be able to decide to create the subsites as sub domains or as sub folders.
For example, if your main site top domain is my-network.com, and you configured your Multisite installation to create subsites as sub domains, then you will be able to create new subsites as: site1.my-network.com, site2.my-network.com, site3.my-network.com and so on.
Instead, if you configured the subsite as sub folders, you will be able to create new sub sites as my-network.com/site1, my-network.com/site2, my-network.com/site3 and so on.
2. Domain Mapping: the roadmap
Now that your WordPress Multisite installation is up and running, in order to properly map the domains related to the subsites of your network we will proceed with the following steps:

Configure DNS for the Domains
Add the Domains to the WordPress Multiste hosting account
Map each subsites in your Multisite Network to its related Domain

Of course, if you are in a live environment, before performing any change we strongly suggest you to create a backup of your site.
3. DNS System
When you write a domain name in your browser, the computer uses the DNS system to retrieve the actual address related to that particular domain.
In that way it can reach the system that hosts your site.
In order to relate your subsite with a domain you need also to properly update the DNS system.
But in case your hosting package provides the main domain for your site, the connection between this domain and the root of your network site should be already set.
Instead, if this is not true, and hence you registered the domains (both the main network site and the subsites) with a different provider, first you should properly connect the main domain to your network site.
This tutorial explains how to achieve that. After that, each subsite domain can be then similarly configured.
How this configuration has to be performed it could also be vary, depending on your particular hosting provider.
Check your hosting service documentation for further info.
3.1. DNS Configuration
In general, the information needed are the following:

CNAME Record: this info maps an alias name to the domain name. Typically maps a sub domain such as www or mail to the primary domain hosting. For example, a CNAME record can map www.my-network.com to the domain my-network.com.
A Record: this info maps a domain name to the IP address (IPv4) of the server hosting the domain.
AAAA Record: this info maps a domain name to the IP address (IPv6) of the server hosting the domain.
Nameservers: the hosting service provides these kind of info: Nameservers let you connect the domain with the Ip address of your hosting account.

When setting up your DNS, the info we describe here could be set in different ways depending on your hosting service. Also, you may not actually need and/or set all of them.
But in any case, after setting the DNS info, it will take from 24 to 48 hours before the changes take effect.
This is due to the DNS propagation time: the info that link your host to the referenced domains have to be set along all the required servers in the web before the routing of your site is properly managed.
4. Add Domain to Hosting
In this step we need to set our domain in the hosting account.
To perform this action you just need to add the domain to the Parked Domains or Alias lists. You can find them in the domains section in the interface provided by your hosting provider. One of these for example, is the CPanel application.
But in general, also here,  settings depends on the particular hosting provider you are referring to.
After adding your domains to the Parked Domains or Alias, is then possible connect them to your subsites.
Let』s see how to accomplish that in the section below.
5. Map Domain to subsite
Now we need to map the domain to the related subsite in your Multisite Network. To do so you have to log into your WordPress back end and access to the Network Admin Dashboard.
From there, head to MySites -> Network Admin -> Sites and then in the subsite list select the one you want to map clicking on the Edit link.
Now you are in the sub site Edit page: fill in the Site Address (URL) field the domain you want to map.
 
Sub site setting page: map the domain
This way, WordPress will consider this sub site with the set custom domain, rather than the default sub domain or sub directory Url extension.
6. Install SSL Certificate
Finally, for security reason and SEO benefit, it is good practice to set an SSL certificate for each subsite. The SSL encryption in fact protects the communication.
Furthermore, the SSL protocol makes your site more reliable for search engines, which will consider that, and hence rank higher your sites in the Serp.
Again, SSL certificate could be provided by default by your hosting and its activation could vary depending on the provider.

WordPress multisite compatible plugins – the definitive list

WordPress multisite compatible plugins – the definitive list

WordPress multisite compatible plugins – the definitive list
Are you currently building a WordPress multisite network? Do you already have one and are looking for plugins to equip your network with additional features? Then it』s inevitable that you will deal with the question of WordPress multisite compatible plugins. That』s because  you cannot use all plugins within a multisite.
Now we will explain how you can tell whether a WordPress plugin is compatible with the multisite feature or not. Moreover, we provide a long list of plugins that we update regularly.

Table of Contents

How do I know whether a plugin is compatible with WordPress multisite?List of WordPress multisite compatible plugins
1. How do I know whether a plugin is compatible with WordPress multisite?
Generally, the plugin description mentions compatibility with WordPress multisite if it is compatible. For free plugins, you can find this description at wordpress.org. Nevertheless, you can divide a plugin』s compatibility with WordPress multisite into three categories:

a) non-compatible – The plugin delivers an error message during installation or activation in a WordPress multisite. You definitely cannot use these plugins in a multisite. For many of these plugins, there is nothing in the plugin description about multisite compatibility.
b) passively compatible – You can use the plugin in the multisite without causing errors but the plugin author didn』t specifically develop the plugin as a multisite plugin. You can use these plugins in the multisite, but you should exercise caution if the plugin author does not specifically indicate multisite compatibility in the description.
c) actively compatible – These plugins are always referred to as multisite compatible in the description. These are a safe option for you.

If you are not sure, it』s best to contact the plugin author.
2. List of WordPress multisite compatible plugins
To spare you a long search, we have compiled several plugins here that are known to be WordPress multisite compatible along with a brief description and a link to the plugin.

Plugin NameURL and Description

Akismethttps://de.wordpress.org/plugins/akismet/
Protects against spam comments.

Antispam Beehttps://de.wordpress.org/plugins/antispam-bee/
Protects against spam comments, GDPR compliant alternative for Akismet

BackWPuphttps://backwpup.de
Backup-plugin with restore functionality and multisite features. Multisite backup possible.

Broken Link Checkerhttps://wordpress.org/plugins/broken-link-checker/
Finds incorrect links on your website. Passive multiste compatible.

Contact Form 7https://wordpress.org/plugins/contact-form-7/
The most popular plugin to create contact forms.

GDPR Cookie Consenthttps://wordpress.org/plugins/cookie-law-info/
Formerly "Cookie Law Info". Displays a cookie information. Passive multisite compatible.

Imagifyhttps://wordpress.org/plugins/imagify/
Lossless picture optimization to improve the performance of your website.

Jetpackhttps://wordpress.org/plugins/jetpack/
A plugin made by Automattic, the provider of WordPress with many modules like site statistics, marketing and security features.

MailChimp for WordPresshttps://wordpress.org/plugins/mailchimp-for-wp/
Connects your website with your Mailchimp account and provides forms with which you can collect newsletter subscriptions.

Monster Insightshttps://wordpress.org/plugins/google-analytics-for-wordpress/
Integrates Google Analytics into your website, ecommerce tracking in its pro version.

MultilingualPresshttps://multilingualpress.de
Our plugin for performant multilingual websites based on WordPress multisite.

NextGen Galleryhttps://de.wordpress.org/plugins/nextgen-gallery/
The most popular plugin to create galleries.

Optimushttps://de.wordpress.org/plugins/optimus/
A plugin to optimize pictures, like Imagify.

Redirectionhttps://de.wordpress.org/plugins/redirection/
Setup 301 redirections in the WordPress backend. Capable to implement all regular expressions.

Search & Replacehttps://de.wordpress.org/plugins/search-and-replace/
Enables to search and replace character strings in the database. Database backup and database restore inclusively.

SEOPresshttps://wordpress.org/plugins/wp-seopress/
A powerfull SEO plugin which helps you optimize your site.

Stream https://de.wordpress.org/plugins/stream/
Monitoring of user activities in WordPress multisite.

User Switchinghttps://de.wordpress.org/plugins/user-switching/
Allows the simple switching of the admin into the profile of another website user.

W3 Total Cachehttps://de.wordpress.org/plugins/w3-total-cache/
Caching plugin for WordPress. Improves the website performance and therefore the SEO and the user experience.

WooCommercehttps://woocommerce.com/
THE ecommerce solution for WordPress. Many free and fee-based extensions available.

Wordfence Securityhttps://de.wordpress.org/plugins/wordfence/
Security checks and measures for your website like firewall, scans of data, prevention of brute force attacs.

Yoast SEOhttps://de.wordpress.org/plugins/wordpress-seo/
The most famous search engine optimization plugin for WordPress helps you increase traffic to your site.

NEW! MultilingualPress Yoast SEO Sync available for free on Github - This is a simple add-on for the MultilingualPress 3 plugin to synchronize the post metadata of the Yoast SEO plugin between translated posts.

How to get a post from another site in the network

How to get a post from another site in the network

How to get a post from another site in the network
This tutorial is part of our MultilingualPress 2 documentation. In case you are using the newer version 3, please switch to MultilingualPress 3.
Let』s say we have a site id and a post id. The source doesn』t matter, it could be a database, user input, whatever. Now we want to get a WP_Post object from that site.
A first idea might look like this:
switch_to_blog( $site_id );
$post = get_post( $post_id );
restore_current_blog();
But this is not necessary, there is already a function in WordPress for that:
function get_blog_post( $blog_id, $post_id ) {
switch_to_blog( $blog_id );
$post = get_post( $post_id );
restore_current_blog();

return $post;
}
Nice, but there is an important, subtle bug in that function: it is using get_post( $post_id ) without a check on the post id. If $post_id is 0, NULL or "", get_post() will use an existing global post object or id. But the current global post is from the source site, not from the target site! The id on site 1 references a completely different post than on site 2.
WordPress doesn』t care. So we have to do that check:
$post = NULL;

if ( ! empty ( $post_id ) )
$post = get_blog_post( $site_id, $post_id );

How to translate custom post types and taxonomies

How to translate custom post types and taxonomies

How to translate custom post types and taxonomies
In this document we explain you how to translate custom post types and taxonomies in MultilingualPress. To demonstrate it, we』ll create a WordPress Multisite installation with two connected sites.
We are going to use the Custom Post Type UI plugin to create a custom post type and a taxonomy. Just keep in mind that the process is the same for any other plugin that creates custom post types or if you register them manually using register_post_type and register_taxonomy.

Table of Contents

Setup a WordPress Multisite with 2 connected sitesInstall and setup Custom Post Type UI pluginCreate a new custom post type and a taxonomyEnable Custom Post Types and Taxonomies in MultilingualPress SettingsEnter Post Type slug value on each siteCreate some custom posts and taxonomy termsConnect Taxonomy Terms with MultilingualPressConnect Custom Post Types with MultilingualPressCreate a menu on each site to navigate through languagesSetup Permalinks structureVisit a Custom Post page and switch language
1. Setup a WordPress Multisite with 2 connected sites
To setup a WordPress Multisite you can follow our tutorial How to install and set up a WordPress Multisite. Our guide Getting started with MultilingualPress 3 explains how to create the sites and connect them with MultilingualPress. We created 2 sites, one for English and one for German and connected them as you can see in the screenshot below.
Two sites in a WordPress multisite for English and German connected with MultilingualPress
2. Install and setup Custom Post Type UI plugin
In the next step we install and activate the Custom Post Type UI plugin. Regarding plugin activation we need to decide if it should be network activated or activated in each site individually. The decision will depend on the plugins ability to support Multisite or not. In this case Custom Post Type UI does not have Multisite support (at least in the free version) so we activate it on each site. To do so, go to the Dashboard of each site and activate the plugin on the Plugins page.
Install the plugin Custom Post type UI which we want to use for creating our custom post type and custom taxonomy.
3. Create a new custom post type and a taxonomy
We first create the custom post type and taxonomy on site 1 and afterwards we will copy them to site 2. We will call our custom post type Recipes and the taxonomy Ingredients.
Create a custom post type Recipes
Create a custom taxonomy Ingredients.
To copy the custom post type and taxonomy we use the Export/Import functionality in the Tools page of Custom Post Type UI.
Copy the content of the Export Post Type settings field from site 1…
… And paste into the field Import Post Types of  site 2.
In the next step we do the same export/import for taxonomies via Taxonomies tab.
4. Enable Custom Post Types and Taxonomies in MultilingualPress Settings
Now that we have custom post type and taxonomy created in both sites, we can configure MultilingualPress in order to be able to translate them. To do so go to My Sites → Network Admin →  Settings →  MultilingualPress and enable the custom post type and the taxonomy in the corresponding tabs, in our case Recipes and Ingredients.
Enable Recipes in Translatable Post Types tab.
Enable Ingredients in Translatable Taxonomies tab.
5. Enter Post Type slug value on each site
Before to proceed, please note that MultilingualPress does not translate custom post type slugs, that should be done at registration time via rewrite parameter from register_post_type (e.g. 『rewrite』 => [『slug』 => esc_html__(『my-cpt』, 『text-domain-here』)] ) and with language files (.po/.mo, .pot). When you have the slugs properly translated then you can tell MultilingualPress which slug to use on each site.
In case you need  to also set the archive page for your custom post type, and then be able to translate it, then you should also have the has_archive parameter set to true when registering the post type; and any custom slug for archive pages should not be specified.
Besides, if the language set in your profile and the one selected in a particular subsite are not the same, the solution above described will be not enough.
In this case, if your profile language and the subsite language are different, you have also to add the following snippet to your code, for example in the functions.php file:
/**
* Updates the rewrite => slug argument when registering a post type.
*
* Will use the option from the "Post Type Slugs" tab the
* Network Settings of a website, in case it』s not empty.
*
* @see register_post_type()
*
* @param array $args An array of arguments that will be passed to register_post_type().
* @param string $postType The name/slug of the post type.
*
* @return array Updated arguments.
*/
add_filter( 'register_post_type_args', function( $args, $postType ) {

if ( ( isset( $args['_builtin' ] ) && $args['_builtin'] )
|| ( isset( $args['public'] ) && ! $args['public'] )
) {
return $args;
}

$slugSettings = get_network_option(
0,
InpsydeMultilingualPressCoreAdminPostTypeSlugsSettingsRepository::OPTION,
[]
);

$siteId = get_current_blog_id();

if ( empty( $slugSettings[ $siteId ][ $postType ] ) ) {
return $args;
}

$args = array_merge( $args, [
'rewrite' => [
'slug' => $slugSettings[ $siteId ][ $postType ]
],
] );

return $args;
}, 10, 2 );
With that filter, doesn』t matter what language is selected in your language settings: the right Custom Post Type slug will be used.
Now we can go on to set our Post Type Slug.
To do so go to My Sites →  Network Admin →  Sites and edit each site. In Post Type Slugs fill in the value of the custom post type slug for our custom post type Recipes. In this case both sites use the same slug, but this feature allows you to setup a different translated slug on each site.
But consider also that when you register a custom post type and you don』t want to translate that post type』s slug, even in that case you should fill in the value in the Post Type Slugs tab in order to let the language menu work correctly.
Enter a slug for your custom post type on each site
6. Create some custom posts and taxonomy terms
We can start creating ingredients (taxonomy terms) and recipes (custom posts) in site 1 and then we use the MultilingualPress translation metabox to create the translations for site 2 from there. It is also possible to connect existing content in site 2 from the same translation metabox.
Create some Ingredients in site 1.
Create Recipes and assign Ingredients in site 1.
7. Connect Taxonomy Terms with MultilingualPress
After creating the taxonomy terms on the different language sites we need to connect them.  Go to the dashboard of site 1, select Recipes → Ingredients and edit one term. In the translation metabox you can choose Create a new term or Select an existing term. In this case we choose Create a new term. We can fill the fields in Term Data tab manually otherwise the values will be generated automatically for you.
Connect taxonomy terms in the MultilingualPress translation meta box
8. Connect Custom Post Types with MultilingualPress
Connecting the custom posts is similar to connecting taxonomy terms. Go to the dasboard of site 1, select Recipes in the menu and edit one.  In the translation metabox you can choose Create a new Recipe or Select an existing Recipe. We choose Create a new Recipe. You can setup the values manually and use advanced features like Copy featured image in Advanced tab.
Connect custom post types with MultilingualPress
Now if you go to site 2 you will see a new Recipe created. Edit it and select a translated taxonomy in the Ingredients metabox:
Select an Ingredients taxonomy term in the Ingredients taxonomy metabox
9. Create a menu on each site to navigate through languages
Now that we have some recipes and ingredients connected between both sites we create a menu on each site to allow the user to switch between languages. In the menu we will add MultilingualPress language items.
Create a language menu on each site to allow users to switch languages and add language items to it
10. Setup Permalinks structure
Before we check that switching languages works, we need to ensure that our permalinks structure is configured correctly. Depending on if it is a new Multisite installation it could be that our permalink includes a /blog/ slug added by WordPress. The best approach for now is to simply get rid of this part in the permalink:
Remove /blog/ from URLs
A quick tip for removing the /blog/ slug from the permalink is to select Plain and save. Then select Custom Structure and remove /blog/ slug there. You need to remove the /blog/ slug in both sites. Don』t forget to 301 redirect the old slugs to the new.
11. Visit a Custom Post page and switch language
Now that everything is setup correctly, its time to check that we can switch languages from a custom post type page. Go to site 1 and view one of the Recipes you』ve set up. Then switch languages in the menu. You should be redirected to the translated version. Do the same also for the taxonomy terms.
View a Recipes post …

… and switch the language
View an ingredient…

… and switch the language
That』s all you need to do regarding setting up custom post type and taxonomy translations in MultilingualPress. If you have doubts or need further assistance, just let us know.

How to set up a Language Switcher for multilingual WordPress Websites

How to set up a Language Switcher for multilingual WordPress Websites

How to set up a Language Switcher for multilingual WordPress Websites
A language switcher gives your site visitors the possibility to switch between the languages you provide on your multilingual site and thus to read the content in their preferred language. With MultilingualPress you can set up a language switcher either via a navigation menu or via a menu widget.
Here you can find a step by step guide for setting up the language switcher.

Table of Contents

Set up a language switcher in your navigation menuSet up language switcher via a widgetShow language flags
1. Set up a language switcher in your navigation menu
Follow these steps if you want to show a language switcher in your navigation menu as you can see it in the screenshot below.

Go to Appearance→ Menus.

Click on the link Create a new menu and enter a name. Afterwards click the button Create Menu.
Create a new menu and enter a name for the menu, e.g. Main Menu
After that, in the left sidebar open the Languages dropdown. If this dropdown is not visible yet, you first need to activate it: open the Screen Options menu and select the Languages checkbox.
You can use Screen Options to display the languages box in the sidebar.
If you have opened the Languages box on the left, then you will see all language versions of your website (e.g. German and English). Now check the languages that you want to be shown in the language menu. Then click Add to menu.
Use the Languages toggle to add the languages that should appear in the menu.
Now the selected languages are shown in the language switcher menu. You can change the order of the languages using drag & drop or if you click on Move while the languages box is open. You can also change the name of the language as it appears on your website in the Navigation Label field.
Make individual changes in the language menu.
Finally, the following advanced settings are also available:

You can optionally specify an HTML attribute title.
By ticking Open link in a new tab, you can indicate that the language will open in a new tab.
You can also optionally customize the CSS classes and link relationships (XFN).
In the description you can write a short info about the language. However, this is only displayed if the theme you are using supports displaying.

If you do not see these options, is because you have to open the upper menu Screen Options again and check the Show advanced menu properties checkboxes.
Then click Save Menu.
In order to let your visitors see the language menu, you have to assign a position to the menu in the theme. To do this, switch to the Manage Locations tab. Select your language menu in one of the available locations and then click Save Changes.
Determine the position of your Language menu.

2. Set up language switcher via a widget
If you want your language switcher to appear in the sidebar of your website, make the following settings.

Go to Appearance → Widgets.
There you will see various widgets available. Select the Navigation Menu widget. Drag and drop it into your sidebar.
Select the menu in which you created the language links (see Setting up the language switcher using the navigation menu, steps 1 to 6).

3. Show language flags
We have developed a small plug-in for MultilingualPress 3, which enables you to display flags in the language switcher. All you have to do is install the plugin and activate it across the network. You can get the additional plugin from us requesting it in our Support.
Show flags via an additional MultilingualPress 3 plugin

How to run code when the 「Copy source content」 option is checked

How to run code when the 「Copy source content」 option is checked

How to run code when the 「Copy source content」 option is checked
In this tutorial we are going to show how to run your code snippet when the option Copy source content is selected in the translation metabox.

Table of Contents

The translation metaboxFilter the code and run your snippet
The translation metabox
A translation metabox lets you to define some settings related to the post translations that are available in another language sub site.
When you edit a post you will find the translation metabox right under your content. There will be one metabox for every language site connected through MultilingualPress.
In each metabox it is possible to quickly set some options that affect the post content and configuration in the related language sub site. This way the user can set all the needed options directly in one page.
The option 「Copy source content」 lets you copy the entire content of the post to the related translation post.
For further information please refer to: https://multilingualpress.org/docs/getting-started-with-multilingualpress-3/
Filter the code and run your snippet
If you need to run some code only when that option is checked, you can use the multilingualpress.sync_post_meta_keys filter.
Here below we provide an example of such implementation.
add_filter('multilingualpress.sync_post_meta_keys', function($keysToSync, $context, $request) {

$multilingualpress = $request->bodyValue(
'multilingualpress',
INPUT_POST,
FILTER_DEFAULT,
FILTER_FORCE_ARRAY
);

$remoteSiteId = $context->remoteSiteId();
$translation = $multilingualpress["site-{$remoteSiteId}"] ?? '';

if(!empty($translation) && $translation['remote-content-copy'] === '1') {
// Copy source content checked in metabox
}

return $keysToSync;
}, 10, 3);
So, here we see that by using the multilingualpress.sync_post_meta_keys filter hook, you can grab from the context the translation metaboxes, and then loop through them.
While looping you can check the status of the related remote-content-copy array key. That value is set accordingly with the Copy source content option.
Finally replace the comment 「Copy source content checked in metabox」 with your code snippet. This will run when the status is 1.

A basic plugin for MultilingualPress

A basic plugin for MultilingualPress

A basic plugin for MultilingualPress
This tutorial is part of our MultilingualPress 2 documentation. In case you are using the newer version 3, please switch to MultilingualPress 3.
Plugins for MultilingualPress should wait until MultilingualPress is actually loaded. That means they should use a hook provided by the main plugin to be sure that MultilingualPress is running and ready to be used. There are three main entry hooks:

inpsyde_mlp_init: equals to plugins_loaded, 0 plus MultilingualPress loaded. Happens before scripts and stylesheets are registered. The only parameter is an instance of the class Inpsyde_Property_List ↓ which holds useful plugin information.
inpsyde_mlp_loaded: Almost the same, but after the scripts are registered.
mlp_and_wp_loaded: equals to wp_loaded, 0 plus MultilingualPress loaded. The first parameter is again the same Inpsyde_Property_List. When in doubt use this action.
wp_loaded happens after WordPress has checked if the current blog was marked as spam. Unless you want to run your code on spam blogs, wait for this action.

When we use type hints in our callback function, we should declare the dependency for the first parameter against the interface Inpsyde_Property_List_Interface, not against a concrete class.

Table of Contents

First exampleThe class Inpsyde_Property_ListThe autoloader
First example
(All code examples here require at least PHP 5.3.)
add_action(
'mlp_and_wp_loaded',
function( Inpsyde_Property_List_Interface $mlp_data ) {
// your code here
});
The class Inpsyde_Property_List
This class is very similar to a stdClass from the PHP core: just some key-value pairs. There are two important differences: an Inpsyde_Property_List can be made immutable, and it can have a parent class.
To make an instance of this class immutable, we call its method freeze(). Once that is done, there is no way to change any data of this class. Any attempt to do that will return an instance of WP_Error. We can test that with the method is_frozen() which returns true or false, depending on the current state.
The instance we get from MultilingualPress is always frozen. We can rely on its data, because no matter how many plugins access it, they cannot change it.
What should we do if we want an instance with almost the same data, but some of them with different values? We create a new instance and use the existing one as its parent. Now we can change the values for our internal use and use the other values as if they were properties of our new instance.
Usage example for Inpsyde_Property_List
add_action(
'mlp_and_wp_loaded',
function( Inpsyde_Property_List_Interface $mlp_data ) {

$ours = new Inpsyde_Property_List;
$ours->set_parent( $mlp_data );

$ours->plugin_url = plugins_url( '/', __FILE__ );
$ours->css_url = "{$ours->plugin_url}css/";
$ours->js_url = "{$ours->plugin_url}js/";
$ours->image_url = "{$ours->plugin_url}images/";

$ours->freeze();
});
This approach avoids common problems with classic inheritance, like the fragile base class and statically linked dependencies. We could call it delayed inheritance. The concept is explained in Steve Yegge』s article The Universal Design Pattern.
We will look at the various default properties from MultilingualPress in a separate article. For custom code, we need just one important property:
The autoloader
The property loader holds an instance of the class Inpsyde_Autoload, a very simple Collection Pipeline for instances of the Inpsyde_Autoload_Rule_Interface which handle the actual class loading. Sounds complicated, but it is dead simple.
Let』s say our plugin is organized like this:
- plugin.php // the main file
- css/ // stylesheets
- js/ // scripts
- php/ // PHP classes
- Plugin_Name_Controller.php
- Plugin_Name_Model.php
- Plugin_Name_View.php
Now we want set up an autoloader to get our classes when we need them. There is one existing class for that, we can reuse it to create a new auto-load rule: Inpsyde_Directory_Load. It takes a path to a directory, and we pass its instance to the Inpsyde_Autoload instance provided by $mlp_data->loader.
Usage example for Inpsyde_Autoload
add_action(
'mlp_and_wp_loaded',
function( Inpsyde_Property_List_Interface $mlp_data ) {

$load_rule = new Inpsyde_Directory_Load( __DIR__ . '/php' );
$mlp_data->loader->add_rule( $load_rule );

// We can just use our classes now, no 'require' needed.
$model = new Plugin_Name_Model( 'foo' );
$view = new Plugin_Name_View( $model );
$controller = new Plugin_Name_Controller( $model, $view );
$controller->setup();
});
All we have to take care of is that the class names match the file names. This works for interfaces and traits too. Inpsyde_Directory_Load works with flat directories only, it doesn』t search in child directories. It is very fast, because the complete directory is read just once. There is no separate file_exists() check for every class name.
And that』s all we need for a start: Hook into mlp_and_wp_loaded, register the directory for the auto-loader with the help of the property list – and write awesome code!

MultilingualPress 3 authors tutorial

MultilingualPress 3 authors tutorial

MultilingualPress 3 authors tutorial
This MultilingualPress 3 tutorial is intended to quickly show to content authors how to create and update the content in a Multilingual site.
So we describe some common tasks focusing on the authors activities and not on the administration tasks of the Multisite Network and/or the MultilingualPress settings and configuration.
We assume instead that these kind of configuration is already properly set in the environment you are going to use.
For more info about these topics, you can refer to our docs: Getting started with MultilingualPress 3 and MultilingualPress 3 – Common Questions & Answers

Table of Contents

Routine activities in MultilingualPress 3Publish new contentPublish translationHow to go further?
1. Routine activities in MultilingualPress 3
An author can normally deal with these routine tasks:

Publish new content with related terms (categories and tags)
Publish translations for that new content and terms in the available languages

Here we want to provide an example that shows how to perform such tasks. To do that we refer to a Multisite environment with 3 language sites: English, Italian, German.
Being this an example, we will not go through every detailed feature and configuration that MultilingualPress offers. These info are already available in the above links.
Instead we want to guide an Author describing some basic steps he should perform, in order to understand how MultilingualPress works and how to continue further to exploit all the power that the plugin and the Multisite Network can unleash.
Let』s see how to create some content and manage the related translation in the following sections.
1.1. Publish new content
Suppose we need to create a new blog post in our main English site.
That operation is really straightforward, since you can perform it as usual, like in a standard WordPress site.
In fact, just log into the English version site back end, then in the left menu head to Post -> Add New .
There you can work on the content, create tags and/or categories, as usual.
After all of the content is provided we can focus on the translation part.
You can manage that by the so called translation metaboxes: just have a quick look at them in your post edit page, scrolling down the page to the bottom.
There you will find one language metaboxes for each language site you have connected. So, in our example 2 language metabox: one for the German site and another one for the Italian site translation, as shown in the picture below.
Post Translation Metaboxes
Similarly, after creating a tag and a category in order to associate them to your post, open them in edit mode, and you will find again at the bottom of the edit page the metaboxes needed to properly manage the terms translation.
Check the images below for the  categories and tags metaboxes.
Categories and Tags Translation Metaboxes
Through this metaboxes is possible to easily manage the translation.
Let』s have a look in the next section of this MultilingualPress 3 tutorial how this can be accomplished.
1.2. Publish translation
In the previous section we created a post in the English site version and created also one  (or more) categories and tags that have been set for the post.
Now we want to create the translations for the Italian and German version site.
This can be achieved in different ways: MultilingualPress is very flexible and many tasks can be performed in different ways.
Here we show one of this way, but as soon as you get more confidence with the Multisite environment and with MultilingualPress you will be able to find your own way for manage the translation in your sites.
Translate Categories and Tags
For the moment so, we first proceed in translating the category.
Go in the category edit page and then in the metabox select 「Create a new term, and use it as translation in Italiano」 . Then select the 「Term」 tab, and fill the name of the translated category.
Perform the process again also for the German metabox and finally press the Update button.
This way a category will be created in the Italian and the German sub sites, as a translation of the main one you are updating in the English version site.
Repeat all this process for the tag, since the process is the same: open it in edit mode and create the translations through the metaboxes.
Translate your post
Now go back to the post created in the English site, and scroll the page to reach the translation metaboxes.
Here, in Italian translation metabox select 「Create a new Post, and use it as translation in Italiano (Italia)「. After that several tabs are available. For each of them perform the action as explained here below:

Title and Content: fill the 「New post title」 field, and in case you need, select the checkbox: this way the English text will be duplicated in the Italian site. This could be useful in case you want to perform the translation in Italian later, having the original text available in the same post
Advanced: in the new post status select 「Publish「; this way on the Italian site you publish the post directly with the English text
Taxonomies: in this section select the checkbox for the category and the tag translated as explained in the previous section

Now that you set the requested data in the Italian translation metabox, proceed similarly with the German metabox too. Finally press the Update button.
This way a new post is created in each site: the Italian and German one. The English text is the content set for all the post, while the category and tag are properly translated.
These post will be all in published status.
The next step will be to log into the Italian and German sub sites to provide the actual translations. For example log into the Italian back end, select the new post you created and replace the English content with the actual Italian content, as needed.
Finally update your posts: the Italian and German translation are now published.
We reached to goal of this MultilingualPress 3 tutorial for authors.
1.3. How to go further?
What we saw is a very simple example of what is possible to achieve with MultilingualPress. But there are many more options available.
For example, consider the activation of the Quicklinks in the MultilingualPress settings in order to have always a link in the post that let you easily navigate from a language site to another.
Also be aware that we created this example starting to work on the English site, but this was just a casual choice. In fact you can get the same results working first on the Italian or the German site.
Practice is the best way to master the Multisite environment and the MultilingualPress features, so go on trying, and check also all the info provided in our official documentation here.

WordPress Multisite database tables explained

WordPress Multisite database tables explained

WordPress Multisite database tables explained
Working with a WordPress Multisite requires a little bit more knowledge about WordPress and experience as WordPress admin than working with a single site. When you try to fix problems with your WordPress Multisite network, it is sometimes helpful to know how the database of a multisite is structured and what the differences between a Single Site database and a WordPress Multisite database are.
So let』s take a look to which database tables do we have in a single site and which we have in a multisite. We will briefly explain each of the multisite specific tables. If you need an explanation of single site tables, please read the post Database Description in the WordPress Codex.
Hint: Starting from a single site WordPress installation it is possible to switch to a WordPress Multisite through a procedure as described in the WordPress codex.

Table of Contents

WordPress single site database tablesWordPress Multisite database tablesNew tablesUpdated tablesSite Specific Tables
1. WordPress single site database tables
In a single site WordPress installation the database tables used are:

wp_commentmeta
wp_comments
wp_links
wp_options
wp_postmeta
wp_posts
wp_terms
wp_termmeta
wp_term_relationships
wp_term_taxonomy
wp_usermeta
wp_users

After we proceed with the Multisite install procedure, some of these tables are updated and other new tables are added. The remaining ones are not changed but they start to refer to the main site, while for other sites (not the main) specific ones are created.
2. WordPress Multisite database tables
So here the new situation after a Multisite install:

wp_blogs → NEW
wp_blogs_versions → NEW
wp_commentmeta → refers to main site
wp_comments → refers to main site
wp_links → refers to main site
wp_options → refers to main site
wp_postmeta → refers to main site
wp_posts → refers to main site
wp_registration_log → NEW
wp_signups → NEW
wp_site → NEW
wp_sitemeta → NEW
wp_terms → refers to main site
wp_termmeta → refers to main site
wp_term_relationships → refers to main site
wp_term_taxonomy → refers to main site
wp_usermeta  → UPDATED
wp_users  → UPDATED
SITE SPECIFIC TABLES → NEW, refers to other site(s) except the main one

2.1. New tables

wp_blogs: each site created is stored in that table
wp_blogs_versions: this table keeps track of the datadase version status for each site
wp_registration_log: in this table is stored the admin user created when a new site is created
wp_signups: in this table are stored the users that have registered for a site via the login registration process.
wp_site: in this table is stored the sites address
wp_sitemeta: here are tracked various site informations

2.2. Updated tables

wp_users: the list of all users of all the sites is maintained in this table
wp_usermeta: here are stored the meta data of users for all the sites

2.3. Site Specific Tables
The data of the main site is stored in existing unnumbered tables, while the data of additional sites is stored in new numbered tables.
So for the main site we have these dedicated tables:

wp_commentmeta
wp_comments
wp_links
wp_options
wp_postmeta
wp_posts
wp_terms
wp_termmeta
wp_term_relationships
wp_term_taxonomy

While, for example, when a new site is created, the site-specific tables, similar to the single site install, are created. Each set of tables for a site is created with the site ID (blog_id) as part of the table name. These are the tables that would be created for site with ID 2 :

wp_2_commentmeta
wp_2_comments
wp_2_links
wp_2_options
wp_2_postmeta
wp_2_posts
wp_2_terms
wp_2_termmeta
wp_2_term_relationships
wp_2_term_taxonomy

References:
https://codex.wordpress.org/Database_Description
https://deliciousbrains.com/wordpress-multisite-database-tour/
https://rudrastyh.com/wordpress-multisite/database-tutorial.html

How to link the sites of your WordPress multisite with each other

How to link the sites of your WordPress multisite with each other

How to link the sites of your WordPress multisite with each other
This tutorial is part of our MultilingualPress 2 documentation. In case you are using the newer version 3, please switch to MultilingualPress 3.
You need to have a site for each language within your multisite installation in order to translate your website. The next step is to link the sites of your WordPress multisite.  Afterwards you will be able to translate your posts and pages.
Follow these steps to link the sites of your WordPress multisite with each other

Go to Network Admin → Sites. There are all existing sites listed, with the page』s language and all linked sites.
Attention: You can only link sites when you assigned them to a language before.

Edit your desired site, then go to the tab MultilingualPress.
The section Relationships shows all existing sites which you assigned to a language. Choose the sites you want to link and save your settings.
Choose the sites you want to link and save your settings
Go to Network Admin → Sites. There, you will see the newly created links.