How to Display Opening Hours for Restaurants - P1 - Using Meta Box + Gutenberg
Tags: metabox, tutorials, opening, hours
Published: 2022-02-09 04:59:07

Each restaurant or business will have different opening hours. To have that information and display them for each on a website, there might be some techniques including using custom fields. We’re going to <strong>add an Opening Hours section into the single restaurant page</strong> in this tutorial as this example:

<!--more-->

<img class="aligncenter" src="https://i.imgur.com/B6FJkVp.png" alt="The example of adding an Opening Hours section into the single restaurant page." width="1200" height="787" />
<h2>Before Getting Started</h2>
For having extra information such as time slots for each day, we’ll use custom fields. So, we need the <a href="https://metabox.io/">Meta Box plugin</a> to have a framework to create them. It’s free and available on <a href="https://wordpress.org/plugins/meta-box/">wordpress.org</a>. Furthermore, we also need some advanced features from Meta Box that are available in the following extensions:
<ul>
 	<li><a href="https://metabox.io/plugins/mb-views/">MB Views</a>: a premium extension of Meta Box. It helps you create templates and display the custom fields’ value on the frontend without touching the theme’s files;</li>
 	<li><a href="https://metabox.io/plugins/meta-box-builder/">Meta Box Builder</a>: this premium extension of Meta Box provides an intuitive UI in the back end to create and configure custom fields without using code;</li>
 	<li><a href="https://metabox.io/plugins/meta-box-group/">MB Group</a>: this extension helps to arrange fields into groups;</li>
 	<li><a href="https://metabox.io/plugins/meta-box-conditional-logic/">MB Conditional Logic</a>: this premium extension allows you to create rules to control the display of the fields.</li>
</ul>
After installing and activating all these plugins, let’s move to the how-to parts right now.
<h2><span id="video-tutorial">Video Tutorial</span></h2>
https://youtu.be/8nZwyBbAWXU
<h2>Step 1: Create Custom Fields</h2>
Normally, we will create a new custom post type for the restaurants first. I skipped that step since I already had it on my website. If you haven’t had it yet, create it first then go to this step.

Go to <strong>Meta Box</strong> &gt; <strong>Custom Fields</strong> &gt; <strong>Add New</strong> to create a new field group. Then, add custom fields with the structure like this:
<table style="height: 2025px;" width="1310">
<tbody>
<tr>
<td><b>Name</b></td>
<td><b>ID</b></td>
<td><b>Type</b></td>
<td><b>Options</b></td>
<td><b>Condition</b></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Choose an option</span></td>
<td><span style="font-weight: 400;">choose_an_option</span></td>
<td><span style="font-weight: 400;">select</span></td>
<td><span style="font-weight: 400;">1. all_days_are_the_same</span>
<span style="font-weight: 400;">2. difference_between_weekdays_and_weekend</span>
<span style="font-weight: 400;">3. custom</span></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">All days have the same opening hours</span></td>
<td><span style="font-weight: 400;">all_days_have_the_same_opening_hours</span></td>
<td><span style="font-weight: 400;">group</span></td>
<td></td>
<td>display only when:
the <code>choose_an_option</code> field = the <code>all_days_are_the_same</code> option</td>
</tr>
<tr>
<td><span style="font-weight: 400;">Type of opening hours</span></td>
<td><span style="font-weight: 400;">type_of_opening_hours</span></td>
<td><span style="font-weight: 400;">select</span></td>
<td><span style="font-weight: 400;">1. open_all_day</span>
<span style="font-weight: 400;">2. close_all_day</span>
<span style="font-weight: 400;">3. by_appointment_only</span>
<span style="font-weight: 400;">4. enter_hours</span></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Choose time slots</span></td>
<td><span style="font-weight: 400;">choose_time_slots</span></td>
<td><span style="font-weight: 400;">group</span></td>
<td></td>
<td>display only when: the <code>type_of_opening_hours</code> field = the <code>enter_hours</code> option</td>
</tr>
<tr>
<td><span style="font-weight: 400;">Start time</span></td>
<td><span style="font-weight: 400;">start_time</span></td>
<td><span style="font-weight: 400;">time picker</span></td>
<td></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">End time</span></td>
<td><span style="font-weight: 400;">end_time</span></td>
<td><span style="font-weight: 400;">time picker</span></td>
<td></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Weekdays</span></td>
<td><span style="font-weight: 400;">weekdays</span></td>
<td><span style="font-weight: 400;">group</span></td>
<td></td>
<td>display only when: the <code>choose_an_opton</code> field = the <code>difference_between_weekdays_and_weekend</code> option</td>
</tr>
<tr>
<td><span style="font-weight: 400;">Type of opening hours</span></td>
<td><span style="font-weight: 400;">type_of_opening_hours</span><b>_weekdays</b></td>
<td><span style="font-weight: 400;">select</span></td>
<td><span style="font-weight: 400;">1. open_all_day</span>
<span style="font-weight: 400;">2. close_all_day</span>
<span style="font-weight: 400;">3. by_appointment_only</span>
<span style="font-weight: 400;">4. enter_hours</span></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Choose time slots</span></td>
<td><span style="font-weight: 400;">choose_time_slots</span><b>_weekdays</b></td>
<td><span style="font-weight: 400;">group</span></td>
<td></td>
<td>display only when: the <code>type_of_opening_hours_weekdays</code> field = the <code>enter_hours</code> option</td>
</tr>
<tr>
<td><span style="font-weight: 400;">Start time</span></td>
<td><span style="font-weight: 400;">start_time</span><b>_weekdays</b></td>
<td><span style="font-weight: 400;">time picker</span></td>
<td></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">End time</span></td>
<td><span style="font-weight: 400;">end_time</span><b>_weekdays</b></td>
<td><span style="font-weight: 400;">time picker</span></td>
<td></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Weekend</span></td>
<td><span style="font-weight: 400;">weekend</span></td>
<td><span style="font-weight: 400;">group</span></td>
<td></td>
<td>display only when: the <code>choose_an_opton</code> field = the <code>difference_between_weekdays_and_weekend</code> option</td>
</tr>
<tr>
<td><span style="font-weight: 400;">Type of opening hours</span></td>
<td><span style="font-weight: 400;">type_of_opening_hours</span><b>_weekend</b></td>
<td><span style="font-weight: 400;">select</span></td>
<td><span style="font-weight: 400;">1. open_all_day</span>
<span style="font-weight: 400;">2. close_all_day</span>
<span style="font-weight: 400;">3. by_appointment_only</span>
<span style="font-weight: 400;">4. enter_hours</span></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Choose time slots</span></td>
<td><span style="font-weight: 400;">choose_time_slots</span><b>_weekend</b></td>
<td><span style="font-weight: 400;">group</span></td>
<td></td>
<td>display only when: the <code>type_of_opening_hours_weekend</code> field = the <code>enter_hours</code> option</td>
</tr>
<tr>
<td><span style="font-weight: 400;">Start time</span></td>
<td><span style="font-weight: 400;">start_time</span><b>_weekend</b></td>
<td><span style="font-weight: 400;">time picker</span></td>
<td></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">End time</span></td>
<td><span style="font-weight: 400;">end_time</span><b>_weekend</b></td>
<td><span style="font-weight: 400;">time picker</span></td>
<td></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Monday</span></td>
<td><span style="font-weight: 400;">monday</span></td>
<td><span style="font-weight: 400;">group</span></td>
<td></td>
<td>display only when: the <code>choose_an_option</code> field = the <code>custom</code> option</td>
</tr>
<tr>
<td><span style="font-weight: 400;">Type of opening hours</span></td>
<td><span style="font-weight: 400;">type_of_opening_hours</span><b>_monday</b></td>
<td><span style="font-weight: 400;">select</span></td>
<td><span style="font-weight: 400;">1. open_all_day</span>
<span style="font-weight: 400;">2. close_all_day</span>
<span style="font-weight: 400;">3. by_appointment_only</span>
<span style="font-weight: 400;">4. enter_hours</span></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Choose time slots</span></td>
<td><span style="font-weight: 400;">choose_time_slots</span><b>_weekend</b></td>
<td><span style="font-weight: 400;">group</span></td>
<td></td>
<td>display only when: the <code>type_of_opening_hours_monday</code> field = the <code>enter_hours</code> option</td>
</tr>
<tr>
<td><span style="font-weight: 400;">Start time</span></td>
<td><span style="font-weight: 400;">start_time</span><b>_weekend</b></td>
<td><span style="font-weight: 400;">time picker</span></td>
<td></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">End time</span></td>
<td><span style="font-weight: 400;">end_time</span><b>_weekend</b></td>
<td><span style="font-weight: 400;">time picker</span></td>
<td></td>
<td></td>
</tr>
<tr>
<td><span style="font-weight: 400;">…</span></td>
<td><span style="font-weight: 400;">…</span></td>
<td><span style="font-weight: 400;">…</span></td>
<td><span style="font-weight: 400;">…</span></td>
<td><span style="font-weight: 400;">…</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Sunday</span></td>
<td><span style="font-weight: 400;">…</span></td>
<td><span style="font-weight: 400;">…</span></td>
<td><span style="font-weight: 400;">…</span></td>
<td><span style="font-weight: 400;">…</span></td>
</tr>
</tbody>
</table>
As you saw in the table above, the first field is a select field and there are 3 options that I filled in the <strong>Choice</strong> box as below.

<img class="aligncenter" src="https://imgur.com/1NRJFk7.png" alt="Fill in the Choice box for the select field." width="1200" height="629" />

These 3 options will be used to set the display rule of other group fields.

To set conditions to groups, for example, with the <strong>All days have the same opening hours </strong>group. Go to the <strong>Advanced</strong> tab, and then set the rule in the <strong>Conditional Logic</strong> section like this:

<img class="aligncenter" src="https://imgur.com/K3AHpVa.png" alt="Set conditional logic for the All days have the same opening hours group." width="1200" height="629" />

This rule means this group will be displayed when the <strong>Choose an Option</strong> field is selected as <strong>All days have the same opening hours</strong> option which has the value is <code>all_days_are_the_same</code>.

Similarly, if the <strong>Choose an Option</strong> field is chosen as the <strong>Difference between weekdays and weekend</strong> options, all the subfields of the <strong>Weekdays</strong> and <strong>Weekend</strong> group will be displayed. Or if the <strong>Choose an Option</strong> field is selected as the <strong>Custom</strong> option, the group fields for every day in a week will be shown up. That’s the concept of how to create fields.

In each group field, I also have subfields with the same structure.

The <strong>Type of Opening Hours</strong> field is the select field. I have 4 options in the <strong>Choice</strong> box:
<ul>
 	<li>Open All day;</li>
 	<li>Close All day;</li>
 	<li>By Appointment Only;</li>
 	<li>Enter Hours.</li>
</ul>
If the restaurant has different opening hours, you can choose <strong>Enter Hours</strong> to display <strong>Start Time</strong> and <strong>End Time</strong> field in the <strong>Choose Time Slots</strong> group. So, I will set the rule for this group like this:

<img class="aligncenter" src="https://imgur.com/sK0dFpU.png" alt="Set the rule when the restaurant has different opening hours." width="1200" height="594" />

In case the restaurant opens in multiple time slots, we’ll need this group to be cloneable. So, I tick this box as below:

<img class="aligncenter" src="https://imgur.com/GHjmy04.png" alt="In case the restaurant opens in multiple time slots, choose cloneable " width="1200" height="629" />

After creating all the fields, go to the <strong>Settings</strong> tab of the field group, choose<strong> Location</strong> as <strong>Post Type</strong>, and select <strong>Restaurant</strong> to apply these fields to this post type.

Publish this field group and go to the post editor in <strong>Restaurant</strong>, you will see the custom fields here.

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

They work exactly like the rule we set.
<h2>Step 2: Display the Fields’ Value on the Frontend</h2>
In this step, we’ll get the input data from those custom fields to display into the Restaurant single page. To do it, we’ll use <a href="https://metabox.io/plugins/mb-views/">MB Views</a> in order not to touch the theme’s file.

If you’ve had a template created by MB Views for the Restaurant single page already, just go to it and edit. If not, create one. Then, add code to the view.

The code is quite long, so I put it in my Github <a href="https://github.com/wpmetabox/tutorials/tree/master/showing-opening-hours-section-with-MB-Views">here</a>. You can refer to it for more details. The code is divided into several parts to get corresponding group data. Because of the same concept in all parts, I’ll explain a typical part to be more clear about the logic.

```
<div class="opening-hours">
<h2>
	Opening Hours
</h2>
<div class="detail-schedule">
	{% set options = post.choose_an_options.value %}
	{% if (options == "all_days_are_the_same") %}
		{% set same_days = post.all_days_have_the_same_opening_hours.type_of_opening_hours.value %}
		{% if ( same_days == "enter_hours") %}
		<div class="date-time">
			<div class="date">
				Mon - Sun
			</div>
			<div class="hour">
			{% for clone in post.all_days_have_the_same_opening_hours.choose_time_slots %}
			<div class="time-slot">
				<p class="starting-hour">
					{{ clone.start_time | date( 'h:i A' ) }}
				</p>
				<p class="ending-hour">
					{{ clone.end_time | date( 'h:i A' ) }}
				</p>
			</div>
			{% endfor %}
			</div>
		</div>
	{% else %}
	<div class="date-time">
		<div class="date">
			Mon - Sun
		</div>
		<div class="hour">
			{{ post.all_days_have_the_same_opening_hours.type_of_opening_hours.label }}
		</div>
	</div>
	{% endif %}

```
Here I created a variable named <strong>options</strong> to admit the value from the <strong>Choose an Option</strong> field. Then I set a rule based on its value to display values from the subfield in the corresponding group. It’s quite the same with the rules we created when configuring the fields.

First, if its value is <code>all_day_are_the_same</code>, the values of fields in the <strong>All days have the same opening hours</strong> group will be displayed.

<img class="aligncenter" src="https://imgur.com/VrN5mY3.png" alt="Get the value of field in All days have the same opening hours group." width="1200" height="483" />

I set a variable named <code>same_days</code> to admit the value from the <strong>Type of Opening Hours</strong> field. If it is <code>enter_hours</code>, the <strong>Choose Time Slots</strong> group will be obtained and displayed the data. As we set before, this group is cloneable, so there is a loop here.

<img class="aligncenter" src="https://imgur.com/HzN0YRA.png" alt="Set the value of field in Choose Time Slots group." width="1200" height="482" />

After adding code, depending on if the view is new or not, choose the right <strong>Type</strong> and <strong>Location</strong> for the view in the <strong>Settings</strong> section.

Go to the single Restaurant page and see how the opening hours section displays.

<img class="aligncenter" src="https://imgur.com/XKBAIx0.png" alt="The opening hours section is displayed before styling." width="1200" height="629" />

All the time slots are shown exactly as I input in the backend. But this section doesn't look as good as I want. So, I will add some CSS to style this section in the next step.
<h2>Step 3: Style the Opening Hours Section</h2>
Still, in the view of the single Restaurant page, go to the <strong>CSS</strong> tab.

<img class="aligncenter" src="https://imgur.com/xvHzV6M.png" alt="Go to the CSS tab to style the Opening Hours Section" width="1200" height="629" />

And then, add the code below.

```
.container.detail-restaurant .opening-hours {
    max-width: 300px;
    margin: 0 auto;
    width: 100%;
}

 .container.detail-restaurant .opening-hours h2 {
    margin: 0 0 10px;
	text-align: center;
	border: 4px solid rgba(231,57,72,.85);
    border-right: 0;
    border-left: 0;
}

 .container.detail-restaurant .detail-schedule .date-time {
    display: flex;
    width: 100%;
    justify-content: space-between;
    flex-wrap: wrap;
	align-items: baseline;
}

.container.detail-restaurant .detail-schedule .date-time .hour .starting-hour:after{
    content: '-';
    margin: 0 5px;
}

.container.detail-restaurant .detail-schedule .date-time .hour .time-slot {
    display: flex;
}

.container.detail-restaurant .detail-schedule .date-time .date {
    font-weight: 700;
    font-size: 15px;
}

.container.detail-restaurant .detail-schedule {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
	border-bottom: 4px solid rgba(231,57,72,.85);
    padding-bottom: 10px;
}

```
Now, go back to the single restaurant page, you’ll see the Opening Hours section looks much more beautiful.

<img class="aligncenter" src="https://imgur.com/B6FJkVp.png" alt="The Opening Hours section looks much more beautiful." width="1200" height="787" />
<h2>Last Words</h2>
If you’re running an online food order platform or own a business that has several branches with different time zones, this tutorial may make sense to you. Try it out and share the results in the comment section. For other page builders, we’ll have some upcoming tutorials. By the way, if you have any idea about any other tutorials, feel free to leave a comment. Thank you for reading. Good luck!