How to Display Images from Cloneable Fields - P2 - with Oxygen
Tags: metabox, tutorials, cloneable, oxygen
Published: 2022-03-01 02:41:28

In the previous part of the series “<strong>Display images from cloneable fields</strong>”, we introduced you to do it with Meta Box and Gutenberg. As promised, we are going to show you another method that uses Meta Box and another page builder, <strong>Oxygen</strong>.

<!--more-->

Similar to part one, I also do it with a simple case study, brand logos.

<img class="aligncenter" src="https://i.imgur.com/BDW7pqF.gif" alt="The example of displaying images from cloneable fields using Meta Box + Oxygen." width="1200" height="675" />
<h2>Before Getting Started</h2>
To do it, we need the <a href="https://wordpress.org/plugins/meta-box/">Meta Box core plugin</a> to have the framework to create custom fields. It’s free, so you can download it directly from <a href="https://wordpress.org/plugins/mb-custom-post-type/">wordpress.org</a>. For further advanced features, we also need some extensions of Meta Box as the following:
<ul>
 	<li><a href="https://metabox.io/plugins/mb-settings-page/">MB Settings Page</a>: it helps you to create settings pages, we’ll need a settings page to place the custom fields into.</li>
 	<li><a href="https://metabox.io/plugins/meta-box-builder/">Meta Box Builder</a>: it provides a UI to create custom fields easily.</li>
 	<li><a href="https://metabox.io/plugins/meta-box-group/">Meta Box Group</a>: this extension helps to organize custom fields into cloneable groups, where we input images today.</li>
</ul>
You can install these extensions individually or use Meta Box AIO for having them in one place.

And, the last one is <a href="https://oxygenbuilder.com/">Oxygen</a>. You should use the 3.9 version or upper, which has the native integration with Meta Box.
<h2>Video Version</h2>
https://youtu.be/mUcuw6NGUC4
<h2>Step 1: Create a Settings Page</h2>
Likewise <a href="https://metabox.io/display-images-from-cloneable-fields-p1-gutenberg/">the 1st part of this series</a>, I’m creating a settings page to save all the brands’ data instead of creating a custom post type. With custom post type, information of each brand will be saved in a separate post. But with a settings page, all of them will be on this page only.

Go to <strong>Meta Box</strong> &gt; <strong>Settings Page</strong> &gt; <strong>Add New</strong>. The creating settings page is used to save brands’ logos and names so there is no advanced configuration for it. I just changed the option name.

<img class="aligncenter" src="https://i.imgur.com/8fiH4O7.png" alt="Create a Settings Page" width="1200" height="689" />

After publishing, a new menu named <strong>Brands</strong> appears. It’s my new settings page.

<img class="aligncenter" src="https://i.imgur.com/FahlhsS.png" alt="The new Settings Page named Brands appears." width="1200" height="673" />
<h2>Step 2: Create Custom Fields for the Settings Page</h2>
In the admin dashboard, go to <strong>Meta Box</strong> &gt; <strong>Custom Fields</strong> &gt; <strong>Add New</strong>. The following table illustrates the fields’ structure that I’m using.
<table>
<thead>
<tr>
<th>
<p style="text-align: left;"><b>Field</b></p>
</th>
<th style="text-align: left;"><b>Types of Field</b></th>
<th>
<p style="text-align: left;"><b>ID</b></p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td><span style="font-weight: 400;">Brand Group</span></td>
<td><span style="font-weight: 400;">Group</span></td>
<td><span style="font-weight: 400;">brand_group</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">          Brand Logo Upload</span></td>
<td><span style="font-weight: 400;">Single Image</span></td>
<td><span style="font-weight: 400;">brand_logo_upload</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">          Brand Logo Url</span></td>
<td><span style="font-weight: 400;">Url</span></td>
<td><span style="font-weight: 400;">brand_logo_url</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">          Brand Name</span></td>
<td><span style="font-weight: 400;">Text</span></td>
<td><span style="font-weight: 400;">brand_name</span></td>
</tr>
</tbody>
</table>
This is a group with three subfields inside. This group is also set to be cloneable to have more spaces to add different brands' information.

<img class="aligncenter" src="https://i.imgur.com/gBaeRlj.png" alt="Set this group as cloneable to have more spaces to add different brands' information." width="1200" height="683" />

As you can see in the structure, I added 2 fields which are <strong>Single Image</strong> and <strong>URL</strong>. One allows you to upload images and save them in the library, and one allows you to input a link of an image from anywhere.

<img class="aligncenter" src="https://i.imgur.com/PQfSDvD.png" alt="2 fields which are Single Image and Url help you upload images and input a link of image." width="1200" height="680" />

After having all the needed fields, go to the <strong>Settings</strong> tab and choose the <strong>Location</strong> as the settings page that we’ve just created to apply the custom fields to it.

<img class="aligncenter" src="https://i.imgur.com/ekJcofh.png" alt="In the Settings tab, choose the Location as the Settings Page to apply the custom fields." width="1200" height="674" />

Back to the settings page, you’ll see all of the created custom fields. There is an <strong>Add more</strong> button to add another brand’s information.

<img class="aligncenter" src="https://i.imgur.com/qoa79Hf.gif" alt="The created custom fields are displayed." width="1200" height="675" />

Now, let’s fill the information into the fields and move to the next step.
<h2>Step 3: Display Images from the Fields</h2>
To add a section for displaying brands’ information, go to the <strong>Edit with Oxygen</strong> section of the page you want.

First, add a <strong>Div</strong> component.

<img class="aligncenter" src="https://i.imgur.com/3MkQvE2.png" alt="Choose a Div component to add a section for displaying brands’ information." width="1200" height="680" />

Next, add a <strong>Code Block</strong> inside the <strong>Div</strong>. Then, add code to the <strong>PHP&amp;HTML</strong> section.

<img src="https://i.imgur.com/N81hHSZ.png" alt="The PHP&amp;HTML section of Code Block" width="1200" height="675" />

<img src="https://i.imgur.com/h1S0Ip4.png" alt="Add code to the PHP&amp;HTML section" width="1200" height="675" />

I’m using this code, you can refer to it.

```
<?
$group = rwmb_meta( 'brand_group', ['object_type' => 'setting'], 'brand' );
?>
<div class="brand-group">
	<?php foreach( $group as $value): ?>
		<?php
			$image = RWMB_Image_Field::file_info( $value['brand_logo_upload'], ['size' => 'thumbnail'] );
		?>
		<div class="brand-img">
			<?php  if (!empty($image)): ?>
				<img src="<?php echo $image['url']?>"/>
			<?php  elseif (!empty($value['brand_logo_url'])): ?>
				<img src="<?php echo $value['logo_url'] ?>"/>
			<?php  else: ?>
				<img src="<?php echo $image['url']?>"/>
			<?php endif; ?>
			<p class="name"><?php echo $value['brand_name'] ?></p>
		</div>
	<?php endforeach; ?>
</div>
			<p class="name"><?php echo $value['brand_name'] ?></p>
		</div>
	<?php endforeach; ?>
</div>

```
<strong>Explanation</strong>:
<ul>
 	<li><code>$group = rwmb_meta( 'brand_group', ['object_type' =&gt; 'setting'], 'brand' );</code>: create the <code>$group</code> variable to get the value of the field which has the ID as <code>brand_group</code>, from the object which has type as settings page and name as <strong>Brands</strong>. You can change the name of this variable as you want, but please make sure you input exactly the field ID and object name as yours.</li>
<li><code>&lt;?php foreach( $group as $value): ?&gt;</code>: since the <code>brand_group</code> the field is cloneable, I create a loop to get value from the <code>$group</code> variable.</li>
 	<li><code>&lt;?php echo $value['brand_name'] ?&gt;</code>: get and display the value from the field <code>brand_name</code>.</li>
</ul>

```
<?php  if (!empty($image)): ?>
	<img src="<?php echo $image['url']?>"/>
```
This means that if the <code>$image</code> variable there is no value, means that there is an uploaded image in the <strong>Single Image</strong> field, we’ll display the image from its returned value.
```
<?php  elseif (!empty($value['brand_logo_url'])): ?>
	<img src="<?php echo $value['logo_url'] ?>"/>

```
On the other hand, if there is any value in the <strong>URL</strong> field, which has ID as <code>brand_logo_url</code>, we will display the image from that link.
```
<?php  else: ?>
	<img src="<?php echo $image['url']?>"/>

```
In the event that both of these fields have value, we set priority here to display the image from the <strong>Single Image</strong> only.
After adding code, click <strong>Apply Code</strong>.

Now, you can see all of the brand logos along with their names displayed in the live preview already.

<img class="aligncenter" src="https://i.imgur.com/EetMvob.png" alt="After editing with Oxygen, the brand logos along with their names displayed already." width="1200" height="681" />

But it hasn’t looked good yet. Thus, we’ll need some JS and CSS to make it look good with a better layout.
<h2>Step 4: Create Slider for the Brand Logos</h2>
As you can see at the beginning of this post, the logos are in a slider, and brand names are displayed correspondingly. To do this, I’ll use some JS and CSS.

However, instead of adding them directly to the theme, I'm using the <strong>My Custom Functionality</strong> plugin. Therefore, when I change the theme, the slider won't be affected. You can download this plugin from <a href="https://github.com/srikat/my-custom-functionality">Github</a>.
<h3>Download the JS and CSS Library</h3>
For the JS and CSS, I use the Slick library which also can be found on <a href="https://github.com/kenwheeler/slick">Github</a>. It contains several files, but we need only three of them.

<img class="aligncenter" src="https://i.imgur.com/kzkblUd.png" alt="JS and CSS files in the Slick library." width="1200" height="609" />

Then, go to the folder of the <strong>My Custom Functionality</strong> plugin, and upload them into the corresponding JS and CSS folders.

<img class="aligncenter" src="https://i.imgur.com/28EukKG.png" alt="Upload the slick-theme.css file into the css folder of My Custom Functionality plugin." width="1200" height="676" />
<h3>Create Custom JS for Slider and Rules</h3>
To set up the slider effect of Slick Slider, I’ll create a <code>custom.js</code> file in the <code>JS</code> folder, and add the following code there.

<img class="aligncenter" src="https://i.imgur.com/Jh3yf7b.png" alt="Add code to custom.js file." width="1200" height="975" />

```
jQuery(document).ready(function ($) {
    jQuery(".brand-group").slick({
        infinite: false,
        dots: false,
        autoplay: false,
        speed: 800,
        autoplaySpeed: 4000,
        slidesToShow: 7,
        slidesToScroll: 7,
        nextArrow: '<button class="next-btn">Next</button>',
        prevArrow: '<button class="prev-btn">Previous</button>'
    });
})

```
In there, <code>.brand-group</code> is the class of the elements which are brands’ logos and names.
<h3>Declare the JS and CSS Files</h3>
We need to declare all the JS and CSS files that have just been uploaded by adding this code inside the <code>custom_enqueue_files()</code> function in the <code>plugin.php</code> file.

```
wp_enqueue_style('slick', plugin_dir_url( __FILE__ ).'/assets/css/slick.css');
wp_enqueue_style('slick-theme', plugin_dir_url( __FILE__ ).'/assets/css/slick-theme.css');

wp_enqueue_script('custom', plugin_dir_url( __FILE__ ).'/assets/js/custom.js', ['jquery']);
wp_enqueue_script('slick-min', plugin_dir_url( __FILE__ ).'/assets/js/slick.min.js', ['jquery']);

```
<img class="aligncenter" src="https://i.imgur.com/uAL0dcR.png" alt="Add code in the plugin.php file" width="1200" height="974" />

Now, the brand logos have already turned into a slider.

<img class="aligncenter" src="https://i.imgur.com/b981aUD.gif" alt="The brand images have already turned into a slider." width="1200" height="675" />

However, it still hasn’t looked good yet. So, it’s time to add some additional CSS.
<h2>Step 5: Style the Slider using CSS</h2>
Move to the page editor by Oxygen. In the <strong>Manage</strong> section, choose <strong>Stylesheets</strong> &gt; <strong>Add Stylesheet</strong>.

<img src="https://i.imgur.com/7LneM8I.png" alt="Choose Stylesheets in the Manage section." width="1200" height="650" />

<img src="https://i.imgur.com/ZnJo831.png" alt="Create a new stylesheet" width="1200" height="675" />

Add code to the created stylesheet.

<img class="aligncenter" src="https://i.imgur.com/gDyqesa.png" alt="Add code to the created stylesheet" width="1200" height="670" />

All the CSS code that I’m using is uploaded to <a href="https://github.com/wpmetabox/tutorials/blob/master/display-images-from-cloneable-fields-with-Oxygen/custom.css">Github</a>, you can refer to it.

Now, the slider displays much more beautifully.

<img class="aligncenter" src="https://i.imgur.com/6BlnwTi.gif" alt="The final result of displaying images from cloneable fields with Meta Box + Oxygen." width="1200" height="675" />
<h2>Last Words</h2>
In this practice, I created two fields for the logos so I need a rule to choose which will be displayed. But in the real case, you can have only one field then the execution will be easier by having no condition anymore. Just choose the way you want.

By the way, if you have any idea about any other tutorials, feel free to leave a comment. Thank you for reading. Good luck!