How to get connected post IDs by current post ID

How to get connected post IDs by current post ID

How to get connected post IDs by current post ID
To get an array of connected posts you can use the translationIds function. That method is the equivalent of mlp_get_linked_elements in MultilingualPress 2:
The first parameter is the source post id, the second is the column “type” in the wp_mlp_relationships table in the database and the third parameter is the source site id .
About the type value, this must be either “post” or “term”, depending on whether the
Translation of a post or translation of a term is to be queried:
$translations = InpsydeMultilingualPresstranslationIds(1, ‘post’, 1);
it will return an array of key value pairs as site id and post id:
array (size=2)

1 => int 1

2 => int 1
You can loop through $translations like this:
if($translations) {

foreach($translations as $siteId => $postId) {
echo ‘Site ID: ‘ . $siteId . ‘ Post ID: ‘ . $postId . ‘
‘;
}
}

How to copy post meta to the remote sites

How to copy post meta to the remote sites

How to copy post meta to the remote sites
This code snippet shows how to copy post meta to the remote site(s). In the example it gets the value of yoast_wpseo_title post meta from the request and then updates the value in the connected sites.
add_action(‘multilingualpress.metabox_after_relate_posts’, function($context, $request) {

// get post meta value from source site
$yoastWpseoTitleValue = (string)$request->bodyValue(
‘yoast_wpseo_title’,
INPUT_POST,
FILTER_SANITIZE_STRING
);

// switch to remote sites and save post meta
$remoteSiteId = $context->remoteSiteId();
$remotePostId = $context->remotePostId();
switch_to_blog($remoteSiteId);
update_post_meta($remotePostId, ‘_yoast_wpseo_title’, $yoastWpseoTitleValue);
restore_current_blog();
}, 10, 2);
The above example shows a case when a plugin registers the custom field, but it is also possible to connect custom fields generated by WordPress from Custom Fields UI in post editor, so let say we have created a new custom field my-field in site one and we want to synchronize the value to the same custom field in site 2, once we have created the custom field with the same name in site 2, we can use the multilingualpress.metabox_after_relate_posts action like so:
add_action(‘multilingualpress.metabox_after_relate_posts’, function ($context, $request) {
// switch to source site
switch_to_blog($context->sourceSiteId());

// grab post meta value
$value = get_post_meta($context->sourcePostId(), ‘my-field’, true);

// switch to remote site
restore_current_blog();

// update post meta
update_post_meta($context->remotePostId(), ‘my-field’, $value);
}, 10, 2);

How to programmatically connect content

How to programmatically connect content

How to programmatically connect content
If you want to connect content programmatically across sites you need to know the IDs of the posts you want to connect beforehand. So let say that we have 3 sites with site ids 1, 2 and 3 and we want to connect a post with the following post ids on each site:
post id 42 in site 1
post id 123 in site 2
post id 321 in site 3
Following code snippet creates the $contentIds array of key value pairs with site id as key and post id as value. Afterwards we pass it to the createRelationship method as first parameter to connect the content.
$api = InpsydeMultilingualPressresolve(
InpsydeMultilingualPressFrameworkApiContentRelations::class
);

$contentIds = [
1 => 42,
2 => 123,
3 => 321,
];

$api->createRelationship($contentIds, ‘post’);

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 translate Taxonomy Slugs

How to translate Taxonomy Slugs

How to translate Taxonomy Slugs
In this brief tutorial we show how to translate taxonomy slugs using the multilingualpress.filter_term_public_url filter hook available in MultilingualPress.

Table of Contents

Set the environment for our example code snippetImplement the snippet for slug translation
Set the environment for our example code snippet
Here below we provide an example snippet with two sub sites that have respectively an ID with value 1, and a second one with value 2.
Of course this example uses two sites, but you can extend it: the ID values can be more, and in any case have to be properly set depending on the sites configured in your environment.
Besides, in this example we assume that you previously registered the taxonomy My Taxonomy with slug my-taxonomy-slug in the network.
Implement the snippet for slug translation
In such an environment we can implement the taxonomy slug translation as shown in the filter below.
add_filter(
‘multilingualpress.filter_term_public_url’,
function ($url, $sourceSiteId, $remoteSiteId) {
$fragments = [
1 => ‘my-taxonomy-slug’,
2 => ‘de-my-taxonomy-slug’,
];

if (empty($fragments[$sourceSiteId]) || empty($fragments[$remoteSiteId])) {
return $url;
}

return str_replace(
$fragments[$sourceSiteId],
$fragments[$remoteSiteId],
$url
);
},
10,
3
);
As you can see in the fragments array the proper slug translations are provided for every site. This is a key value pairs array, where keys are site IDs and values are the translated taxonomy slugs. The array elements can be extended depending the number of the sites you have in your Multisite network.
Now, from the MultilingualPress settings, in the Translatable Taxonomies tab enable My Taxonomy.
After that, in site with ID 1 create a new My Taxonomy term as My Term and connect it to site with ID 2. The snippet created will properly manage the translations of the slugs when switching between the two sites.

How to create a custom language switcher in MultilingualPress 3

How to create a custom language switcher in MultilingualPress 3

How to create a custom language switcher in MultilingualPress 3
In this tutorial we will create a custom language switcher using the MultilingualPress 3 API. We will start creating a simple language menu and then convert it to a select dropdown. Finally we will explain how to add the language switcher to a WordPress widget.

Table of Contents

Get translations for the current pageCreate a translations menu at the beginning of Post contentCreate a language switcherAdding the language switcher to a Widget
1. Get translations for the current page
In order to create a language menu you need a way to get the translations for a particular page. MultilingualPress provides the Translations class which accepts search parameter from TranslationSearchArgs class like this:
function multilingualpress_get_translations()
{
$args = InpsydeMultilingualPressFrameworkApiTranslationSearchArgs::forContext(new InpsydeMultilingualPressFrameworkWordpressContext())
->forSiteId(get_current_blog_id())
->includeBase();

$translations = InpsydeMultilingualPressresolve(
InpsydeMultilingualPressFrameworkApiTranslations::class
)->searchTranslations($args);

return $translations;
}
The above function returns an array of translations, each one containing information like remote_url and language info. You can then loop through the array to get the translations:
$translations = multilingualpress_get_translations();

foreach ($translations as $translation) {
$language = $translation->language();
$language_iso_name = $language->isoName();
$language_locale = $language->locale();
$url = $translation->remoteUrl();
}

2. Create a translations menu at the beginning of Post content
Now that we know how to get the translations of a page, we can create a menu. So lets start adding one before the content of the post. To do so we can use the WordPress filter ‘the_content’:
add_filter(‘the_content’, function ($content) {
if (!is_single()) {
return $content;
}

$translations = array_reverse(multilingualpress_get_translations());

if (!$translations) {
return $content;
}

$output = ”;
$items = ”;
foreach ($translations as $translation) {
$language = $translation->language();
$iso_name = $language->isoName();
$url = $translation->remoteUrl();

if ($url) {
$items .= “

  • ${iso_name}
  • “;
    }
    }

    if($items) {
    $output .= ‘

      ‘;
      $output .= $items;
      $output .= ‘

    ‘;
    }

    return $output . $content;
    });
    As you can see at the beginning we return default content in case we are not in a single post page but also in case there are no translations. Then we create the HTML markup for the menu looping through the translations array. Finally we only display the menu in case there are items containing a URL.
    3. Create a language switcher
    We can use part of the previous code but this time we will change the markup to use a select instead of an unordered list:

    foreach ($translations as $translation) {
    $language = $translation->language();
    $iso_name = $language->isoName();
    $locale = $language->locale();
    $url = $translation->remoteUrl();

    if ($url) {
    $items .= “${iso_name}”;
    }
    }

    if($items) {
    $output .= ”;
    $output .= $items;
    $output .= ”;
    $output .= ”;
    $output .= “jQuery(‘#multilingualpress-language-switcher’).change(function() {window.location.replace(jQuery(‘#multilingualpress-language-switcher option’).data(‘url’));});”;
    $output .= ”;
    }

    Also we use a bit of JavaScript to fire a page redirect when selector is changed.
    4. Adding the language switcher to a Widget
    Finally the code snippet below shows how to add the above language switcher to a widget:
    add_action( ‘widgets_init’, function(){

    register_widget( ‘Language_Switcher_Widget’ );

    });

    class Language_Switcher_Widget extends WP_Widget {

    public function __construct() {
    $widget_ops = array(
    ‘classname’ => ‘language_switcher’,
    ‘description’ => ‘Language Switcher’,
    );

    parent::__construct( ‘language_switcher’, ‘Language Switcher’, $widget_ops );
    }

    public function widget( $args, $instance ) {
    echo $args[‘before_widget’];
    $translations = array_reverse(multilingualpress_get_translations());
    if (!$translations) {
    return $content;
    }

    $output = ”;
    $items = ”;
    foreach ($translations as $translation) {
    $language = $translation->language();
    $iso_name = $language->isoName();
    $locale = $language->locale();
    $url = $translation->remoteUrl();

    if ($url) {
    $items .= “${iso_name}”;
    }
    }

    if($items) {
    $output .= ”;
    $output .= $items;
    $output .= ”;
    $output .= ”;
    $output .= “jQuery(‘#multilingualpress-language-switcher’).change(function() {window.location.replace(jQuery(‘#multilingualpress-language-switcher option’).data(‘url’));});”;
    $output .= ”;
    }

    echo $output;
    echo $args[‘after_widget’];
    }
    }

    How to get content translations programmatically

    How to get content translations programmatically

    How to get content translations programmatically
    In order to get current content translations of the current post in MultilingualPress 3, you can use the Translations class passing the arguments via TranslationSearchArgs. Here is an example:
    add_filter(‘the_content’, function($content) {
    $args =
    InpsydeMultilingualPressFrameworkApiTranslationSearchArgs::forContext(
    new InpsydeMultilingualPressFrameworkWordpressContext()
    )->forSiteId(get_current_blog_id())->includeBase();

    $translations = InpsydeMultilingualPressresolve(
    InpsydeMultilingualPressFrameworkApiTranslations::class
    )->searchTranslations($args);

    foreach ($translations as $translation) {
    $postId = $translation->remoteContentId();
    $title = $translation->remoteTitle();
    $url = $translation->remoteUrl();

    $language = $translation->language();
    $bcp47tag = $language->bcp47tag();
    $englishName = $language->englishName();
    $isoCode = $language->isoCode();
    $locale = $language->locale();
    $name = $language->name();
    }

    return $content;

    });
    Now you can loop through the $translations array where each Translation object contains translation data and language information.

    How to get translations programmatically

    How to get translations programmatically

    How to get translations programmatically
    This tutorial is part of our MultilingualPress 2 documentation. In case you are using the newer version 3, please switch to MultilingualPress 3.
    The most important API in MultilingualPress for you is probably the Language API. This API has a method get_translations() that you can use to get a prepared set of translations for posts of any post type, terms of any taxonomy, a search term, the front page or a blog page.
    You can access that API with a filter:
    $mlp_language_api = apply_filters( ‘mlp_language_api’, NULL );
    MultilingualPress will transform that NULL value now into an instance of the class Mlp_Language_Api. In other words: The variable $mlp_language_api is an object now. But you should still test that, just in case the user has deactivated MultilingualPress:
    $mlp_language_api = apply_filters( ‘mlp_language_api’, NULL );

    if ( ! is_a( $mlp_language_api, ‘Mlp_Language_Api_Interface’ ) )
    return;
    As you can see, you should test against the Interface Mlp_Language_Api_Interface, not against the concrete class. This enables other plugins to replace our implementation with a custom translation handler.
    Today, we are looking just at $mlp_language_api->get_translations( $args );

    Table of Contents

    Arguments for Mlp_Language_Api::get_translations()Methods for Mlp_TranslationMethods for Mlp_LanguageExample: Add translation links to the post contentTheme integration
    Arguments for Mlp_Language_Api::get_translations()
    $args is an array, we can pass some options here to tweak the results.

    Name
    Type
    Description

    site_id
    int
    Base site. Usually the current site.

    content_id
    int
    post or term_taxonomy ID, not term ID.

    type
    string
    Either post, term, post_type_archive, search or front_page.

    strict
    bool
    When TRUE (default) only matching exact translations will be included.

    search_term
    string
    If you want to translate a search.

    post_type
    string
    For post type archives.

    include_base
    bool
    Include the base site in returned list.

    All parameters are optional. MultilingualPress will try to find proper values for them. We recommend to set the content_id for terms and posts though, because that is not always available, at least not in a reliable way.
    Now let’s see how our code could look like:
    $mlp_language_api = apply_filters( ‘mlp_language_api’, NULL );

    if ( ! is_a( $mlp_language_api, ‘Mlp_Language_Api_Interface’ ) )
    return;

    $args = array (
    ‘strict’ => TRUE,
    ‘include_base’ => TRUE
    );

    /** @var Mlp_Language_Api_Interface $mlp_language_api */
    $translations = $mlp_language_api->get_translations( $args );

    if ( empty ( $translations ) )
    return;
    Note that $mlp_language_api->get_translations( $args ) will return an empty array if there are no translations even when we set include_base to TRUE.
    Now, let’s say the translations are not empty. We get an array of objects, each an instance of Mlp_Translation which implements the Mlp_Translation_Interface. That sounds complicated, but it just means that we have a set of methods on each object to get information about the translation.
    Methods for Mlp_Translation

    Method
    Return type
    Description

    get_source_site_id()
    int
    The site ID the translation is based on.

    get_target_site_id()
    int
    The ID of the site where the translation can be found.

    get_page_type()
    string
    Either post, term, post_type_archive, search or front_page.

    get_icon_url()
    Mlp_Url_Interface
    An object, an instance of a class implementing the Mlp_Url_Interface. It has a magic method __toString(), so we can cast it to a string and get an escaped URL.

    get_target_title()
    string
    The title of the translation, for example the post title or the term name.

    get_target_content_id()
    int
    The term_taxonomy_id or the post id. This is empty for other translation types like post type archives or search.

    get_remote_url()
    string
    The URL for the translation.

    get_language()
    Mlp_Language_Interface
    An object, an instance of a class implementing the Mlp_Language_Interface.

    The Mlp_Translation::get_language() object deserves an explanation. It has three public methods.
    Methods for Mlp_Language

    Method
    Return type
    Description

    get_priority()
    int
    A number between 0 and 10. See the post about Language negotiation for an explanation.

    is_rtl()
    bool
    Whether the translation is in a right-to-left language (like Hebrew) or not.

    get_name( $name )
    string
    Different representations of the language. Default is the language in its native writing, eg. Deutsch for German. We strongly recommend to use that, because that’s most easily to recognize for your readers.
    Other allowed parameters are english to get the English name, http to get the HTTP value (for example de-AT) or custom to get the custom name you have set in the site properties.
    You can also use language_short to get just the first part of a language code with subsets, eg. just de.

    Example: Add translation links to the post content
    Let’s see what we can do with all this code. The following example adds very simple translation links to the post content. It uses the first part of the language code and sets it to uppercase. The images are used too, if they are available.
    add_filter( ‘the_content’, function( $content ) {

    if ( ! is_singular() )
    return $content;

    $mlp_language_api = apply_filters( ‘mlp_language_api’, NULL );

    if ( ! is_a( $mlp_language_api, ‘Mlp_Language_Api_Interface’ ) )
    return $content;

    $args = array (
    ‘strict’ => TRUE,
    ‘include_base’ => TRUE
    );

    /** @var Mlp_Language_Api_Interface $mlp_language_api */
    $translations = $mlp_language_api->get_translations( $args );

    if ( empty ( $translations ) )
    return $content;

    $links = array();

    /** @type Mlp_Translation_Interface $translation */
    foreach ( $translations as $translation ) {

    $current = $img = ”;

    if ( $translation->get_target_site_id() === get_current_blog_id() )
    $current = ‘ class=”current”‘;

    $img_url = $translation->get_icon_url();

    if ( ” !== (string) $img_url )
    $img = “ “;

    $text = $translation->get_language()->get_name( ‘language_short’ );
    $text = mb_strtoupper( $text, ‘UTF-8’ );

    $links[] = sprintf(
    %4$s‘,
    $translation->get_remote_url(),
    esc_attr( $translation->get_target_title() ),
    $current,
    $img . $text
    );
    }

    $links = ‘


    . join( ‘ | ‘, $links )
    . ‘

    ‘;

    return $content . $links;
    });
    The result should look like this:

    Theme integration
    You can use such a function in other places too, of course. In a theme you should add a custom action wherever you need it and assign a callback handler to that action. This way, your theme will not break when the user deactivates MultilingualPress.
    So in a template file add this line:
    do_action( ‘translation_box’ );
    And in your functions.php create a callback function and register it for that action:
    add_action( ‘translation_box’, ‘show_mlp_translation’ );

    function show_mlp_translation() {
    // find and print translation links
    }
    Any questions or suggestions? Or do you have used this tutorial successfully? Please let me know.

    How to disable broken save_post callbacks

    How to disable broken save_post callbacks

    How to disable broken save_post callbacks
    This tutorial is part of our MultilingualPress 2 documentation. In case you are using the newer version 3, please switch to MultilingualPress 3.
    Many plugins are not multisite aware. This is rarely a problem, because each site in a network works almost like a normal site in a single-site installation. But sometimes … things go really wrong.
    There is a hook, the action save_post, that can be called multiple times when a post is saved: one time for each site. Many plugins are not aware of this, they run their own code on every call to save_post without a check for the site context. The result is that they are either deleting user data on the other sites, or they overwrite existing data.
    This happens when MultilingualPress updates the post translations.
    Site A save_post – MultilingualPress {
    creates or updates translations:
    – switch_to_blog( Site B) -> save_post
    – switch_to_blog( Site C) -> save_post
    – switch_to_blog( Site D) -> save_post

    return to Site A
    }
    MultilingualPress removes all POST data before the other save_post actions are called, and it restores it when it switches back. Normal plugins use a nonce as a basic security check before they try to save anything. Since we remove the nonce along with the POST data, they will not do anything. So far, so good.
    Unfortunately, some plugin author don’t use nonces. They just try to save their data, without proper context checks. There is nothing we can do about that.
    But you can. You have to find the code (function or class method) that is registered for the save_post action and then remove it earlier. There is another hook that runs right before save_post: the filter wp_insert_post_data. You can hook your own custom callback to that filter, check if the current context is in a switched site and then remove the “evil” callback. Don’t forget to return the filtered value, that’s necessary for filters.
    Here is an example for the Custom Sidebars plugin:
    add_filter( ‘wp_insert_post_data’, function( $data ) {

    if ( is_multisite()
    && ms_is_switched()
    && class_exists( ‘CustomSidebarsEditor’ )
    ) {
    $cse = CustomSidebarsEditor::instance();
    remove_action( ‘save_post’, array( $cse, ‘store_replacements’ ) );
    }

    return $data;
    });
    If you are a plugin or theme author and want to be sure that your code is safe to run in a multisite: please contact me. I,or one of my colleagues, will look at it and tell you what needs to be changed.

    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!