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:
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:
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.
- MB Views: How To Display Relationships?
- How to Create Reusable Template Parts in WordPress
- How to Create YouTube Video Timestamps on WordPress Website - P1 - Using MB Views
- How to Randomize Hero Image in WordPress - Using MB Views
- How to Display a Video Playlist - Using MB Views
- How to Create a Reading Progress Bar in WordPress Posts - P1 - Using MB Views
- How to Create Reading Time to Your WordPress Posts - Using MB Views
- How to Add Code to Header and Footer in WordPress - Using MB Views
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.
Can you share how did you setup? On my localhost the meta boxes appear on both sides.
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".
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.
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.
Is there a way to do nested Views? So a View, and another View related to the output of the previous View, etc.?
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.
Is there anywhere I could get the theme you are using, please?