In the introduction video of MB Views, we showed you how to use the plugin to get post fields and custom fields to display on singular and archive pages. But MB Views is more powerful than that. It allows you to run almost all PHP code in the view. In this tutorial, we're going to use the plugin to display connected items from relationships, creating with the MB Relationships extension.

Setup

Post Types

Continuing from the previous setup, we already have a post type "Event", which has title, content, featured image and custom fields for date, location, and map.

I'll create another post type "Speaker", which has title, content, featured image and custom fields for Twitter URL and Facebook URL. It's quite easy to do that with the help of MB Custom Post Type (for creating custom post types) and Meta Box Builder. Otherwise, you can also use code if you want. I won't go into the details in this tutorial.

Bonus: this free Custom Post Type Generator will help you create code for custom post types and this free Online Generator lets you create custom fields with UI.

The edit screen for speakers look like this:

The edit screen for speakers

Relationships

To create a relationship between events and speakers (which is a many-to-many relationship), I'm going to use MB Relationships extension. After installing and activating the plugin, add the following code to your theme's functions.php file:

add_action( 'mb_relationships_init', function() {
    MB_Relationships_API::register( [
        'id'   => 'events_to_speakers',
        'from' => [
            'object_type' => 'post',
            'post_type'   => 'event',
            'meta_box'    => ['title' => 'Speakers'],
        ],
        'to' => [
            'object_type' => 'post',
            'post_type'   => 'speaker',
            'meta_box'    => ['title' => 'Event'],
        ],
    ] );
} );

Now go to edit an event or a speaker, you'll see a meta box on the right to choose connected speakers or events accordingly.

Getting connected items in MB Views

Now go to our view. We need to create a view to display single events, where we'll show connected speakers. To know how to create a view for the single event template, please follow our documentation or view the video tutorial.

To get connected items, the documentation of MB Relationships guides us to use WP_Query to make a custom query. However, inside views, we can't do queries like that. So, how to get over this?

The solution is using mb proxy!

mb proxy

In short, the mb allows you to run PHP functions inside views. It acts as a transformer between view and PHP. It's better to explain the idea of the proxy via examples.

Assume you want to get another post in WordPress with post ID 123, you can write a simple PHP code like this:

$post = get_post( 123 );
echo $post->post_title;

With the mb proxy, you can call the get_post() function like this:

{% set post = mb.get_post( 123 ) %}
{{ post.post_title }}

Here you see, the normal PHP function is prefixed by mb., e.g. get_post becomes mb.get_post. So if you want to call a function my_custom_function, you need to write mb.my_custom_function. The parameters passed to the function remain the same.

You might also notice the set syntax in the example above. It's the way Twig uses to set a value to a variable. You can read more about it here.

Besides simple variables, Twig allows you to set complex variables, like lists with keys and values (sorry, Twig doesn't call it an associate array) or without keys, like:

{% set my_var = ["first", "second"] %}
{% set my_var = {first: "first value", second: "second value"}

We'll be using this syntax very much since we need to work with arrays in views. You might also notice that the 2nd form looks very similar to a JSON string!

Querying connected items

Now back to our problem, we need to query connected speakers from the current event. As we can't use WP_Query, we can use the identical get_posts function. But first, we need to set the query arguments.

If we use PHP, we need to make a query like this:

$args = [
    'post_type' => 'speaker',
    'nopaging' => true,
    'relationship' => [
        'id' => 'events_to_speakers',
        'from' => get_the_ID(),
    ],
];
$speakers = new WP_Query( $args );

Then, in views, we need to transform the query arguments into a list of keys and values (remember I said it's similar to JSON strings?):

{% set args = {post_type: 'speaker', nopaging: true, relationship: {id: 'events_to_speakers', from: post.ID}} %}
{% set speakers = mb.get_posts( args ) %}

The only difference between this view and PHP code is the current post ID. In views, it's already available as post.ID, while in PHP it gets via the function get_the_ID().  You can see all available fields in views by clicking the Insert Field button.

Showing connected items

Now we have a list of speakers, we need to loop through them and display their details. To loop through a list, Twig has the for tag. The syntax is very simple:

{% for speaker in speakers %}
    CONTENT HERE
{% endfor %}

For each speaker, we're going to show:

  • Featured image
  • Their names (which is the post title)
  • And links to social profiles

Getting their names is simple, as it's already a property of the post (speaker.post_title), but getting the featured image and social links (which are custom fields) are not straight-forward.

If using PHP, we can get the featured image and custom fields very easily. And you might know the solution here: the mb proxy. So, in this case, we'll use the mb proxy to call PHP functions.

The code looks like this:

{% for speaker in speakers %}
    {{ mb.get_the_post_thumbnail( speaker, 'thumbnail', {class: 'inline-block rounded-full'} ) }}
    <h4>{{ speaker.post_title }}</h4>
    <div>
        <a href="{{ mb.rwmb_meta( 'twitter', '', speaker.ID ) }}">Twitter</a>
        <a href="{{ mb.rwmb_meta( 'facebook', '', speaker.ID ) }}">Facebook</a>
    </div>
</div>
{% endfor %}

As you can see, I use the mb proxy to call the get_the_post_thumbnail and rwmb_meta functions. All the parameters passed to these functions are exactly the same if you do that with PHP.

Note: For the queried posts, only post fields are available (as they're returned as properties of the post object). Custom fields are not available by default, and you need to use a helper function rwmb_meta to get them.

Final code

To polish the output, I continue using TailwindCSS and add some classes to the HTML. I also use FontAwesome icons (SVG) to show Twitter and Facebook links.

The final code of the single event view is available on Github.

And here is the result:

Displaying connected speakers to events
Displaying connected speakers to events

Conclusion

In this tutorial, I have shown you how to use the mb proxy to run PHP functions in views. You also know how to set custom variables and write a for loop in Twig. With the combination of the proxy and the power of Twig, I think the MB Views extension can do a lot more for you.

The drawback of this method is you need to learn Twig and do coding in views. Personally, I think Twig is amazing and not hard to learn. It might take you half an hour to learn most of the basics. The coding part in views is something we're working on to improve. Hopefully, we'll make it easier for you to select and insert these kinds of data via UI without writing code manually.

So, stay tuned, and don't forget to subscribe to our blog to be notified of new tutorials first. And if you have any suggestions or ideas, please let us know in the comments or contact us directly.

8 thoughts on “MB Views: How To Display Relationships?

  1. Thanks, this looks like it could be very useful.

    Just wondering, in this scenario, what if I'd also like to assign Speakers to the Event from the Event edit screen? When I tried this, a metabox only appeared on the Speakers edit screen; No Speakers metabox appeared on Events even though a metabox title is specified.

    1. Can you share how did you setup? On my localhost the meta boxes appear on both sides.

    2. I think you ticked the checkbox "reciprocal relationship" at the top. Then Meta Box thinks you want to connect between the same type and displays the relationship only in the "from" part.

      This was at least my learning curve, misinterpreting the "reciprocal relationship" in the menu as "bi-directional relationship".

  2. Where does the php code go? You keep referring to writing a custom php function for the mb proxy but never where to put that php for the proxy to pull from.

    1. Where we say write PHP code like this, it's mostly in a template file of your theme. But you don't need to write that PHP code, because it's the idea about what the code does. With MB Views, you can write the code for Twig, which does the same job as PHP, inside MB Views in the WP admin.

    1. Yes, that's possible. Inside the Inserter panel, you'll see a tab of existing views, where you can just pick them to insert into the current view.

Leave a Reply

Your email address will not be published. Required fields are marked *