After the 3rd part of the series about how to build a hotel booking website using Meta Box, we had a basic system to create and book reservations for a small and medium hotel. However, I think that you still need a tool to collect all the booking details for easy management and scheduling.
That’s why in this 4th part, I will show you how to display all booking orders on one page so that you can view the booking schedule intuitively as well as easily check each information.
I will use a tool that is pretty similar to Google Calendar regarding the way it displays events. Each booking order will be put to this calendar and display as an event. I hope that this method is suitable for you. Let’s see!
Preparation
To handle all the manipulations in this part, you need to prepare these stuff:
- Make sure that you already followed the instructions in part 1-2-3 in the series. Particularly, in the previous parts, I named my
post_type
asroom
andbooking
and had a field group created with Meta Box plugin calledgroup_booking
in each booking post. If you changed these names in part 1-2-3, in this tutorial, you need to change mine to yours in the code to make it run properly. - Use a jQuery library called FullCalendar. You can read its documentation here.
Now, just start!
Step 1: Create a New Plugin for Booking Management
Create a Folder for the New Plugin
What you need to do first is going to wp-content/plugin
and create a new folder. This folder is used to create a booking management plugin so I name it as mb-hotel-management
. The reason why I use the mb-
prefix is to let you know it’s for Meta Box and to differentiate it with other plugins, avoiding having the same names.
Create the Necessary Folders for the Plugin
Each plugin must at least has two basic files: one main file (.php) and one readme.txt
file.
- The main file (.php) will be used to write code. I name it as
mb-hotel-management.php
. - The
readme.txt
file is to contain information about name, version as well as others of the plugin. If you create this plugin to use for yourself only, you can skip this file.
Here are the files and folders inside the created plugin folder.
As for the main file of the plugin (mb-hotel-management.php
), you need to add the code below and fill in the information to declare the primary information of the plugin.
/** * Plugin Name: * Plugin URL: * Description: * Version: * Author: * Author URL: * License: GPLv2 or later // Plugin license, if you don’t care about it, just keep GPLv2 */
Activate the Plugin
After completing these steps, if you do it correctly you will see your new plugin display in the list of plugins on your website.
Just activate the plugin, then we can start the next steps to build its features.
Step 2: Create a Blank Page on the Backend for the Plugin
This page will be used to display the synthesis of booking orders. The work of adding and displaying the booking orders on this page will be done in the later steps. In this step, we just create a page.
In the inc folder of the plugin, we make a new file named front.php
. Then, open the mb-hotel-management.php
file and add this code:
<?php class BookingManagement { public function __construct() { add_action( 'admin_menu', array( $this, 'create_menu_admin_panel' ) ); } public function create_menu_admin_panel() { add_menu_page( ‘Booking Management’, ‘Booking Management’, 'edit_posts', 'manager-booking', array($this, 'manager_booking' ) ); } public function booking_management() { if (!current_user_can( 'edit_posts' )) { wp_die( __('You do not have sufficient permission to access this page.') ); } include 'inc/front.php'; } } $Init = new BookingManagement(); ?>
Come back to the Admin Dashboard, you will see the Booking Management menu. Click this menu and you will see a blank page because we haven’t had any content for the front.php
file.
Step 3: Import Library and Files to the Plugin
Now, we will import the library and the files to the plugin to customize the template.
Go to the lib folder of the plugin and copy the FullCalendar library to it. You can read more about the necessary files and detailed installation here.
Besides, I will create two more files plugin.css
and plugin.js
in the folder css and js respectively. We will use these 2 files to make modifications or add key functions to the plugin.
Next, add this code to the booking_management()
function that we put to the mb-hotel-management.php
file in order to import the library as well as declare the above custom file.
wp_enqueue_style( 'fullcalendar-core', plugins_url( 'lib/fullcalendar/packages/core/main.css', __FILE__ ) ); wp_enqueue_style( 'fullcalendar-daygrid', plugins_url( 'lib/fullcalendar/packages/daygrid/main.css', __FILE__ ) ); wp_enqueue_style( 'css-custom', plugins_url( 'css/plugin.css', __FILE__ ) ); wp_enqueue_script( 'fullcalendar-core', plugins_url( 'lib/fullcalendar/packages/core/main.js', __FILE__ ) ); wp_enqueue_script( 'fullcalendar-daygrid', plugins_url( 'lib/fullcalendar/packages/daygrid/main.js', __FILE__ ) ); wp_enqueue_script( 'js-custom', plugins_url( 'js/plugin.js', __FILE__ ) );
Then, open the plugin.js
file and add this code:
document.addEventListener('DOMContentLoaded', function() { var calendarEl = document.getElementById('calendar'); var calendar = new FullCalendar.Calendar(calendarEl, { plugins: ['dayGrid'], defaultView: 'dayGridMonth', defaultDate: '2020-02-07', header: { left: 'prev,next today', center: 'title', }, events: [ { title : 'event1', start : '2020-02-27' }, { title : 'event2', start : '2020-02-15', end : '2020-02-17' }, { title : 'event3', start : '2020-02-09T12:30:00', allDay : false // will make the time show } ] }); calendar.render(); });
Finally, open the front.php
file and add this:
<div class="wrap"> <h1 class="wp-heading-inline">Booking Management</h1> <div id='calendar'></div> </div>
Both of the above code is to check if the files and library that we imported into the plugin are working. If you do it correctly, the result will look like this:
Step 4: Build the Features for the Plugin
My idea for the booking management page is that I will create each calendar for each room type. Each event on the calendar will represent a booking order and display as event1, event2, and event3, ... as I created above.
After that, I will create another general calendar. I will put the schedule of all room types into the general calendar so that the hotel manager can view the booking schedule of all room types on one page.
To do it, we need to code a lot in this 4th step and there are quite many ways to customize. You can refer to my method below and feel free to leave a comment if you want any further explanation as well as discussion with us.
Display the Booking Information to the Calendar
I will use AJAX to create a variable containing all the booking orders of the hotel. Then, I will recall the function of FullCalendar to display all these booking orders on the calendar.
In the _contruct
function of the plugin, I’ll create two more actions:
add_action( 'wp_ajax_feed_events', array( $this, 'feed_events_func') ); add_action( 'wp_ajax_nopriv_feed_events', array( $this, 'feed_events_func' ) );
After that, I’ll create the feed_events_func()
function to return the booking calendar under the JSON format below:
public function feed_events_func(){ $args = array( 'post_type' => 'booking', 'posts_per_page' => -1, ); $query = new WP_Query( $args ); if ( $query->have_posts() ) { $events = array(); while( $query->have_posts() ) { $query->the_post(); $bookings = get_post_meta( get_the_ID(), 'group_booking', true ); if ($bookings) { foreach ($bookings as $key => $booking) { $room = $booking['room']; $begin = $booking['check_in']; $end = $booking['check_out']; $e['title'] = "#".get_the_ID().' '.get_the_title($room); $e['start'] = $begin; $e['end'] = $end; $e['url'] = get_edit_post_link(get_the_ID(),''); $e['classNames'] = 'room-'.$room; $e['allDay'] = true; array_push($events, $e); } } } echo json_encode($events); } wp_die(); }
Explanation:
$events
: the array holding all the booking orders information.'title'
,'start'
,'end'
,'url'
, … : the parameters of the event. You can refer to some others here. In this case, I will explain some special parameters, like:- +
'title'
: is the name of the event and will be displayed on the calendar. Here, I name it as#{booking_id}
. - +
'url'
: is the page when users click the booking name on the calendar. - +
'classNames'
: I use it to set the class for each booking order. This will be used and explained more clearly in the next steps.
- +
The next thing to do is opening the plugin.js
file and add this code to download the returned JSON data.
$.ajax({ type: 'post', url: ajaxurl, data: {action: 'feed_events'}, error: function(err){ console.log(err); }, success: function (data) { init_calendar(data); } })
function init_calendar(events){ var calendarEl = document.getElementById('calendar'); var calendar = new FullCalendar.Calendar(calendarEl, { plugins: [ 'dayGrid' ], defaultView: 'dayGridMonth', header: { left: 'prev,next today', center: 'title', right: '' }, events: events, eventPositioned (view, element) { displayBookings(); }, }); calendar.render(); }
Explanation:
- The AJAX is to take the variable of all the booking orders from the
feed_events_func
function. - The
init_fullcalendar(events)
is the initial function but I passed the event variable, which is the data returned by AJAX, to it.
After this step, you will have the calendar of all the booking orders, and these orders will be displayed on the calendar. Clicking each booking order, users will be directed to the booking order page, which is the url
parameter I passed above.
To make it easier to view the booking calendar of each room type, I’ll create a Navbar where each button represents a type of room. When clicking on these buttons, we’re able to view the booking calendar of each room type, and at the same time, the booking calendar of other room types will be hidden.
In this step, we just need to use some CSS and JavaScript.
Because I named the class of each booking order as room-{$room_id}
, I just need to set up to display the corresponding class when clicking a room type. To make it simple, you can understand that I will create a filter by room_id
.
Now, open the front.php
file in the inc folder and add the code below before the calendar declaration <div id='calendar'></div>
. This is to create a navbar containing the list of rooms with each button representing a room.
<div class="navbar mb-4"> <?php $args = array( 'post_type' => 'room', 'posts_per_page' => -1, 'post__not_in' => array(498) ); $query = new WP_Query( $args ); if ( $query->have_posts() ) { echo '<button class="button filter-bookings" data-room="all">ALL</button>'; while( $query->have_posts() ) { $query->the_post(); ?> <button class="button filter-bookings" data-room="<?php the_ID(); ?>"><?php the_title(); ?></button> <?php } } ?> </div>
Explanation: 'post__not_in'
: I passed the ID (498), which is the ID of the extra-bed. In the previous part, I set an extra-bed as a room type, so I don’t want to show it here.
Now I will handle when clicking on each button (one room type), it will only display the booking orders of that room type by adding the following code to the plugin.js
file:
$('.filter-bookings').on('click', function(event){ event.stopPropagation(); var room_id = $(this).attr('data-room'); $('.wrap').attr('class', 'wrap ' + room_id); displayBookings(); }) function displayBookings(){ var classes = $('.wrap').attr('class'); if (classes != 'wrap') { room = classes.replace("wrap ", ""); if (room == 'all') { $('[class*="room-"]').show(); } else { $('[class*="room-"]').hide(); $('.room-'+room).show(); } } }
Explanation:
displayBookings()
is the function to hide all the bookings.$('.filter-bookings')
is to listen to the event when the button on the navbar is clicked.
At this point, you can view each room type by clicking the corresponding button, and the unrelated room types will be hidden. However, when you switch to view the calendar in another month of the year, all the booking orders are still displayed, not hidden. This is because my JavaScript was not executed when the html element was re-rendered. Thus, I have to listen to an event when rendering the booking order and call the function again.
In the FullCalendar v4.0 library, I use a callback named eventPositioned. This callback will be executed when the last event is loaded.
You need to add this code when calling the FullCalendar name:
eventPositioned (view, element) { displayBookings(); }
And this is the final result after you complete all these executions:
And these are all the source code of my created plugin. You can refer to it:
https://github.com/wpmetabox/tutorials/tree/master/hotel-bookings
Final Though
In this part, you also learned the basics of programming a plugin in WordPress and how to use and access the FullCalendar library and its APIs. Although we still haven’t explored each issue deeply, hopefully, this article as well as all 4 articles in this series can open up some ideas and information for you to develop more new functions for the plugin, help you with the booking management on your website.
We also have a series to help you build an OTA site and I think you may be interested.
If you want to share or discuss more with us, feel free to leave a comment!
- How to Build a Hotel Booking Website Using Meta Box - P1
- How to Build a Hotel Booking Website Using Meta Box - P2 - Booking Page in Backend
- How to Build a Hotel Booking Website Using Meta Box – P3 – Booking Page for Customer
- How to Build a Hotel Booking Website Using Meta Box - P4 - Booking Management Page
- How to Build a Hotel Booking Website Using Meta Box - P1
- How to Build a Hotel Booking Website Using Meta Box - P2 - Booking Page in Backend
- How to Build a Hotel Booking Website Using Meta Box – P3 – Booking Page for Customer
- How to Build a Hotel Booking Website Using Meta Box - P4 - Booking Management Page
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
Think to take your business online. A hotel distribution system is the best plan available is a plan as it would help to selling rooms profitably through a variety of channels.
How do I get this plugin to display in WordPress 6.6.2?
As I know, they fixed this plugin with WordPress 6.6.2. So, it works well with the current version. Have you tried installing the plugin? Is there any problem?