The Quando Plugin is for Grav CMS.
It exposes business opening hours and other service hours to Grav as a Twig hash. It provides starter templates you might want to copy into your theme, customise, and include.
Is this fit for your purposes?
There are a few real world scenarios which are not supported yet by the plugin and some bugs affecting some scenarios. Be aware of these issues and make sure they don't affect you before you get too far here:
- No real time refreshes yet (#5)
- Irregular periods containing service hours don't show the hours yet (#4)
- Incomplete/untested microformats support (#3)
- YAML configuration is currently by hand (#2)
It's much simpler to use @bjoernbohr's Opening Hours plugin if that covers your needs. It offers far fewer options for customisation but is much simpler to understand and implement.
Installing the Quando plugin can be done in one of two ways. The GPM (Grav Package Manager) installation method enables you to quickly and easily install the plugin with a simple terminal command, while the manual method enables you to do so via a zip file.
GPM Installation (Preferred)
The simplest way to install this plugin is via the Grav Package Manager (GPM) through your system's terminal (also called the command line). From the root of your Grav install type:
bin/gpm install quando
This will install the Quando plugin into your
/user/plugins directory within Grav. Its files can be found under
To install this plugin, just download the zip version of this repository and unzip it under
/your/site/grav/user/plugins. Then, rename the folder to
quando. You can find these files on GitHub or via GetGrav.org.
You should now have all the plugin files under
Before configuring this plugin, you should copy the
user/config/plugins/quando.yaml and only edit that copy.
Here is the default configuration and an explanation of available options:
enabled: true hours:  # When populated, an indexed array of service hours listings, a complex YAML structure best configured through the Admin dashboard (when the blueprint is done!). One of these listings should be called 'opening' if you want any of the templates to work out of the box.
It's enabled by default on install but will do nothing unless you use it.
Configure the hours through the Admin plugin is probably simplest. Or copy the sample YAML (in fact, you'll have to do that until I add a blueprint for hours).
Copy, customise, and include one of the sample templates, probably start with a simple partial:
Exposed to Twig as 'quando' (formerly 'openhrs'), an indexed array with members named for each property, e.g. 'quando.opening'.
RENAMED from 'Opnhrs'
- Calendar calendar: holds the loaded calendar data for the class instance. RENAMED from 'schedule'
- ServiceTimes __construct(Calendar calendar): instantiate and load a single calendar's data
- boolean availableOn(string day_name, RegularTimetable timetable(=NULL)): return whether service times are in timetable, which defaults to the current calendar's regular timetable. RENAMED from 'opensOn'
- boolean availableAt(DateTime dto): Returns whether the service is available at dto in the current calendar. RENAMED from 'openAt'
- Schedule scheduleOn(string day_name, RegularTimetable timetable(=NULL)): Returns the schedule for day_name in timetable. RENAMED from 'hoursOn'
- string briefTime(string timeOfDay, string pattern(='g.ia'), array truncateZeroComponents(=['.i'])): Convert 24 hour time string to pattern, leaving off the components listed in truncateZeroComponents if they are zero. (static) (exposed as Twig filter)
- array formatSchedule(Schedule schedule, string pattern, array truncateZeroComponents(=)): Format all the timestamps in schedule to
- array statusAt(DateTime dto, boolean includeNext(=TRUE)): Return indexed information about service status at dto, and optionally after the next status change.
- boolean isAvailable(): The service is currently available. RENAMED from 'isOpen'
- DateTime nextChange(DateTime dto, Schedule hours(=NULL)): Returns the time of next status change after dto, hours can be passed as a convenience.
- array schedulesAfter(DateTime start_dto, integer days_duration): Return a date-indexed array of schedules from days_duration days after dto.
- array schedulesWeek(DateTime start_dto, integer days_context(=NULL)): Return a date-indexed array of 7 schedules from days_context days before start_dto.
- Timetable regularTimetable(): Return the
regulartimetable for the current calendar. RENAMED from 'regularSchedule'
- Timetable getTimetable(string member(=NULL)): Return every timetable in the current calendar, or just the one named "member". RENAMED from 'getSchedule'
- array getMeta(string property(=NULL)): Return an indexed array of allowed metadata properties from the calendar ('microdata', 'headings', 'labels'), or just the one named "property" if it's in the allowed list.
Examples in the wild
Please let me know of any others (hey, it's free publicity).
Sponsoring this plugin
This plugin was created out of a client requirement but has been developed beyond that basic and specific capability in my own time, as I've been able to find it. (Not suggesting that's unusual or heroic.)
I recognised that this functionality is likely to be a common requirement, so wanted to make a simple plugin available for everyone to benefit from. Service hours are one of the main things I want to find out from business websites, especially when I have an immediate requirement on a mobile device.
If you would like a specific capability built in, do submit a feature request as an issue here and I will consider it regardless of whether you offer to sponsor its development. However, any contribution is likely to incentivise me to develop it much sooner. Unless your request is very specific to your site (and not useful to others), I will insist that sponsored developments remain open source and therefore free for the community to benefit from. I will gladly credit and link to any sponsors.
I can also help you implement this plugin on your site, although I hope to reach a point where site builders won't need much help. I don't expect payment for this help (within constraints), but please consider contributing if you are able to.
I only request financial contributions because I am currently in a needy situation.
This project's license of course allows you to create and develop your own variant. I also welcome contributions of code, ideas, or documentation.
I had this in my original composer.json for some reason: https://github.com/spatie/opening-hours. I'm sorry, I can't remember, but it looks like I have been inspired heavily by this, its API especially.
It's all supposed to be in the Issues. (Github make it non-trivial for me to reliably link there in any relative way. I'm sorry for that unfortunate fail. But hey, you can do emojis and fontawesome in markdown - that's important, right?)