In a website for booking restaurants, there will be a lot of different restaurants. Definitely, each restaurant has its own opening hours and you may want to create a section for the opening time for each one. So, in this next part of the series, we’re going to figure out how to add an opening hours section into the singular page by Meta Box and Oxygen.
This section will be the same as the last ones we created in the previous post.
Video Version
Before Getting Started
In this case, I want to put the opening hours section for a particular restaurant. And each restaurant including its own information will be displayed on a singular page. So, all the detailed information about the restaurants’ working time will be saved in custom fields stored in the post containing the restaurants’ information.
We’ll display some extra information such as time slots for each day, and we'll use custom fields. So, we need Meta Box plugin to have a framework to create them. It’s free on wordpress.org. We also need additional Meta Box advanced features, which are accessible in the following extensions:
- Meta Box Builder: this premium extension of Meta Box provides an intuitive UI in the back end to create and configure custom fields without using code;
- Meta Box Group: this extension helps to arrange fields into groups;
- Meta Box Conditional Logic: this premium extension allows you to create rules to control the display of the fields.
Finally, Oxygen Builder. Remember to use the 3.9 version or upper to have the native integration with Meta Box.
Create a Custom Post Type
If you read the previous post in this series, you can skip this step. In the event that you haven’t had a post type yet, just create a new one as usual.
Go to Meta Box > Post Types.
Create Custom Fields
This step is the same as what I showed in the previous post about displaying opening hours.
Go to Meta Box > Custom Fields > Add New to create a new field group. Then, add custom fields with the structure like this:
Name | ID | Type | Options | Condition |
---|---|---|---|---|
Choose an option | choose_an_option | select | 1. all_days_are_the_same
2. difference_between_weekdays_and_weekend 3. custom |
|
All days have the same opening hours | all_days_have_the_same_opening_hours | group | display only when:
the choose_an_option field = the all_days_are_the_same option |
|
Type of opening hours | type_of_opening_hours | select | 1. open_all_day
2. close_all_day 3. by_appointment_only 4. enter_hours |
|
Choose time slots | choose_time_slots | group | display only when: the type_of_opening_hours field = the enter_hours option | |
Start time | start_time | time picker | ||
End time | end_time | time picker | ||
Weekdays | weekdays | group | display only when: the choose_an_opton field = the difference_between_weekdays_and_weekend option | |
Type of opening hours | type_of_opening_hours_weekdays | select | 1. open_all_day
2. close_all_day 3. by_appointment_only 4. enter_hours |
|
Choose time slots | choose_time_slots_weekdays | group | display only when: the type_of_opening_hours_weekdays field = the enter_hours option | |
Start time | start_time_weekdays | time picker | ||
End time | end_time_weekdays | time picker | ||
Weekend | weekend | group | display only when: the choose_an_opton field = the difference_between_weekdays_and_weekend option | |
Type of opening hours | type_of_opening_hours_weekend | select | 1. open_all_day
2. close_all_day 3. by_appointment_only 4. enter_hours |
|
Choose time slots | choose_time_slots_weekend | group | display only when: the type_of_opening_hours_weekend field = the enter_hours option | |
Start time | start_time_weekend | time picker | ||
End time | end_time_weekend | time picker | ||
Monday | monday | group | display only when: the choose_an_option field = the custom option | |
Type of opening hours | type_of_opening_hours_monday | select | 1. open_all_day
2. close_all_day 3. by_appointment_only 4. enter_hours |
|
Choose time slots | choose_time_slots_weekend | group | display only when: the type_of_opening_hours_monday field = the enter_hours option | |
Start time | start_time_weekend | time picker | ||
End time | end_time_weekend | time picker | ||
… | … | … | … | … |
Sunday | … | … | … | … |
As you saw in the table above, the first field is a Select field and there are 3 options that I filled in the Choice box as below.
These 3 options will be used to set the display rule of other group fields.
To set conditions to groups, for example, with the All days have the same opening hours group. Go to the Advanced tab, and then set the rule in the Conditional Logic section like this:
This rule means this group will be displayed when the Choose an Option field is selected as All days have the same opening hours option which has the value is all_days_are_the_same.
Similarly, if the Choose an Option field is chosen as the Difference between weekdays and weekend option, all the subfields of the Weekdays and Weekend group will be displayed. Or if the Choose an Option field is selected as the Custom 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 Type of Opening Hours field is select field. I have 4 options in the Choice box:
- Open All day;
- Close All day;
- By Appointment Only;
- Enter Hours.
The second subfield is a Group field named Choose Time Slots. Inside it, there are two subfields: Start Time and End Time.
If the restaurant has multiple opening hours, you can choose Enter Hours to display the Start Time and End Time field in the Choose Time Slots group. So, I will set the rule for this group like this:
In case the restaurant opens in multiple time slots, we’ll need this group to be cloneable. So, I tick this box as below:
After creating all the fields, go to the Settings tab of the field group, choose Location as Post Type, and select Restaurant to apply these fields to this post type.
Publish this field group and go to the post editor in Restaurant, you will see the custom fields here.
They work exactly like the rule we set.
Display the Fields’ Value
We’ll display the opening hours section using Oxygen. If you’ve had a template created by Oxygen for the Restaurant singular page, just go and edit it.
In the event you haven't had one, go to Oxygen > Template > Add New Template to create a new one.
Here, I’ve already had it. So, I just click Edit with Oxygen.
Next, add a new Div component.
In this practice, it includes some complex conditions to choose which fields will be got the value from. However, Oxygen hasn’t supported logic to choose which field yet, we need to use code in this practice. So, I will add a Code Block component.
Then, choose the PHP&HTML and you will see a space to add code.
The code is quite long, so I put it in my Github here. 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.
<?php $options = rwmb_meta( 'choose_an_option' ); ?> <?php if ( $options == "all_days_are_the_same" ): ?> <?php $same_days = rwmb_meta( 'all_days_have_the_same_opening_hours' ); ?> <?php $same_days_option = $same_days['type_of_opening_hours']; ?> <?php $choose_time_slots = $same_days['choose_time_slots'] ?> <?php if ( $same_days_option == "enter_hours" ): ?> <?php foreach ( $choose_time_slots as $time_slots ): ?> <?php echo $time_slots['start_time'] ?> <?php echo $time_slots['end_time'] ?> <?php endforeach; ?> <?php else: ?> <?php $select_field = isset( $same_days['type_of_opening_hours'] ) ? $same_days['type_of_opening_hours'] : ''; $group_field = rwmb_get_field_settings( 'all_days_have_the_same_opening_hours' ); foreach ( $group_field['fields'] as $field ) { if ( empty( $field['options'] ) ) { continue; } ?> <?php if($field['options'][$select_field]): ?> <?= $field['options'][$select_field]; ?> <?php endif; ?> <?php } ?> <?php endif; ?>
Let’s get through each line with me.
<?php $options = rwmb_meta( 'choose_an_option' ); ?>
I created a variable to get the value of the field Choose an Option which has the ID is choose_an_option. We will create a condition based on the returned value to decide which fields will be got the value from.
<?php if ( $options == "all_days_are_the_same" ): ?> <?php $same_days = rwmb_meta( 'all_days_have_the_same_opening_hours' ); ?>
If the returned value is the first option, we will get the value of All days have the same opening hours group.
<?php $same_days_option = $same_days['type_of_opening_hours']; ?> <?php $choose_time_slots = $same_days['choose_time_slots'] ?>
I also have 2 following variables that obtain the value of two fields: Type of Opening Hour and Choose Time Slots. They are the subfields of the All days have the same opening hours group.
Since the Type of Opening Hour is a Select field with some options as the image below, based on the returned value of this field, we’ll get value from the Choose Time Slots group or not.
<?php if ( $same_days_option == "enter_hours" ): ?> <?php foreach ( $choose_time_slots as $time_slots ): ?> <?php echo $time_slots['start_time'] ?> <?php echo $time_slots['end_time'] ?> <?php endforeach; ?>
If the returned value of the Type of Opening Hour field is Enter hours, we’ll display the value from the Choose Time Slots group field with its subfields: Start Time and End Time fields. Since the Choose Time Slots group is cloneable, we have a loop here.
<?php $select_field = isset( $same_days['type_of_opening_hours'] ) ? $same_days['type_of_opening_hours'] : ''; $group_field = rwmb_get_field_settings( 'all_days_have_the_same_opening_hours' ); foreach ( $group_field['fields'] as $field ) { if ( empty( $field['options'] ) ) { continue; } ?> <?php if($field['options'][$select_field]): ?> <?= $field['options'][$select_field]; ?> <?php endif; ?> <?php } ?>
For other options in the Type of opening hours field, the above is used to display the label of that selected option.
That's the end of the first section, corresponding to the first option of the Choose an Option field.
If separate days have different opening hours, call the values from the remaining groups.
The structure of those groups is the same as the All days have the same opening hours group, so just simply follow the same logic in the code.
This section on the page is now displayed like this because this code is for getting data from custom fields only.
To have the display with some other texts as the demo, I’ll add some heading, div tags and class for easier styling later. I’ve uploaded the code on Github, you can refer to it.
Now, all the time slots with some additional texts are shown in the section already.
However, it doesn’t look as beautiful as I want. So, I will add some CSS to style this section in the next step.
Style the Section
For styling, you can go back to the Oxygen visual builder and style each component if any.
In this case, I‘ll add some CSS by going to Manage > Stylesheet and Add Stylesheet.
This is the CSS that I’ve used:
.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; }
Let’s see how the opening hour section displays on the frontend. It’s much more beautiful, isn't it?
To refer to all the code that I used, you can visit here.
Last Words
We’ve gone through all the procedures to display the Opening Hours section using Meta Box plugin and Oxygen Builder. Try it out and let us know how it goes in the comment section. If you have projects using Meta Box and Gutenberg, refer to our prior post in this series. Or if you have any tutorial suggestions, feel free to leave a comment. Thank you for reading. Best of luck!
- How to Display Opening Hours for Restaurants - P1 - Using Meta Box + Gutenberg
- How to Display Opening Hours for Restaurants - P2 - Using Meta Box and Oxygen
- How to Display Opening Hours for Restaurants - P3 - Using Meta Box and Bricks
- How to Display Real-time Opening Status Automatically - Using MB Views
Other series you might be interested in
- Author Bio
- Better 404 Page
- Blogs for Developers
- Building a Simple Listing Website with Filters
- Building an Event Website
- Building Forms with MB Frontend Submission
- Coding
- Create a Chronological Timeline
- Custom Fields Fundamentals
- Design Patterns
- Displaying Posts with Filters
- Download and Preview Buttons
- Dynamic Banners
- FAQs Page
- Featured Products
- Full Site Editing
- Google Fonts
- Gutenberg
- Hotel Booking
- Latest Products
- Logo Carousel
- MB Views Applications
- Meta Box Builder Applications
- Meta Box Group Applications
- Most Viewed Posts
- Opening Hours
- OTA Website
- Product Page
- Product Variations
- Querying and Showing Posts by Custom Fields
- Recipe
- Restaurant Menus
- SEO Analysis
- Simple LMS
- Speed Up Website
- Taxonomy Thumbnails
- Team Members
- User Profile
- Video Gallery
This is great and all, but how would you go about in adding, currently open, or currently closed on the day the person is viewing that data? For ex. Today is Monday and my current time is 8:15pm est, so my view should show, Currently closed (but only for this day) while others show the hours. Same goes when the business is open. You see this on Yelp and Google all the time. Wondering how hard is this to implement and if you can amend this tutorial with that info.