I was on my quest to make my long event calendar dream come true in WordPress. It should
- show each event in its own box with title, date, location, image thumbnail, excerpt, subject and type it is categorized in, written or symbolically as colored dots
- open the event description when clicked in a modal pop-up or as an expanding tab
- be fully responsive
The first plugin I went deeper into was the Time.ly All-in-One Event Calendar, since with its agenda and stream view it already got very close. But the final touch was still missing, so my quest had begun, and my notes became this little All-in-One Event Calendar theme customization tutorial you are about to enjoy …
All-in-One Event Calendar – the first HTML-free theme? No, just a twig
I was searching, and searching. For the HTML frame that generates the calendar view. And I couldn’t find it. Just after an in-file search of some CSS class names I was rewarded with the discovery of TWIG. Never heard of? Me neither up to that moment. As I then figured out, Twig is a template engine for PHP (and I can say it makes working in PHP code a fabulous easy experience), and its files are .twig files. Now the precious HTML structure finally unveiled itself in the /wp-content/plugins/all-in-one-event-calendar/public/themes-ai1ec/vortex/twig folder. (Actually it is all described in theme customization of the All-in-One Event Calendar as I soon after found out.)
Since the agenda view got closest to my vision especially by its functionality with the expandable description (the other path I considered was to integrate a modal pop-up into the stream view), the coding work started here. All-in-One Event Calendar is even equipped with a child-theme system, and we can activate the gamma theme (or copying it before) that sits on top of the vortex fundament. How to do that you find out in the theme customization link above, in short you just need to copy the gamma folder /wp-content/plugins/all-in-one-event-calendar/public/themes-ai1ec/gamma/ into a new folder called /wp-content/themes-ai1ec/. You can then rename the folder “gamma” into your own name, and need to change at least the name of the new theme in its style.css. Now you find your new custom theme in the Event Settings “Calendar Themes” and can activate it here.
All we need for this tuorial quest is the agenda.twig file that you copy from /wp-content/plugins/all-in-one-event-calendar/public/themes-ai1ec/vortex/twig/ into /wp-content/themes-ai1ec/your-theme/twig/. Of course “your-theme” needs to be replaced by the name you gave to your folder. Ready? Here you see our starting conditions, let’s get our hands on the code …
Moving the location in the All-in-One Event Calendar Agenda View
I didn’t like the “Event Title @ Location” style in the agenda view, and even if this can be turned off as an option in the settings, I would not like to remove it in other views, so I removed it directly in the agenda view file in line 39:
1 2 3 4 |
{% if show_location_in_title and event.venue is not empty %} <span class="ai1ec-event-location" >{{ text_venue_separator | format( event.venue ) }}</span> {% endif % |
Yet I wanted to show the location, but together with the time in the second line as in the stream view, so I replaced this code in line 52 (now 48)…
1 2 3 |
<div class="ai1ec-event-time"> {{ event.timespan_short | raw }} </div> |
…with basically this whole block from the stream view wp-content/plugins/all-in-one-event-calendar-extended-views/public/themes-ai1ec/vortex/twig/stream.twig line 56:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div class="ai1ec-event-meta"> <span class="ai1ec-event-time"> <i class="ai1ec-fa ai1ec-fa-calendar"></i> {{ event.timespan_short | raw }} </span> {% if event.venue is not empty %} <span class="ai1ec-tags ai1ec-meta-divide"></span> <span class="ai1ec-event-location"> <i class="ai1ec-fa ai1ec-fa-map-marker"></i> {{ event.venue }} </span> {% endif %} </div> |
Adding Thumbnail Images to the Agenda View
The next step was the thumbnail, and for this we need to add again some lines into our agenda.twig in line 38, right before the {{ event.filtered_title | raw }}:
1 2 3 4 |
<a class="ai1ec-load-event" href="{{ event.permalink | e('html_attr') }}"> {{ event.avatar_not_wrapped | raw }} </a> |
Quite big for the moment, since the All-in-One Event Calendar uses the medium size for all displays, which is good in general, but for the thumbnails I would prefer a smaller squared image.
Creating the most amazing list view with squared and centered thumbnails, working with landscape and portrait images of any size
I know, long headline, but I found no other way to express my happiness explosion when I found out that my preferred behaviour of thumbnails in lists was possible also here. Basically I could just have taken the pre-rendered WordPress 150x150px thumbnail size, but that would have required a core-hack of the plugin due to its structure. Anyhow this is a good moment to spread a bit further an incredible technique that I love so much for gallery overviews and thumbnails in lists, because it allows a coherent display of landscape and portrait formats. Fortunately the All-in-One Event Calendar automatically adds a very special class that we need for this trick: .ai1ec-portrait. Perfect, in our HTML structure all is set already, so here is the CSS code and a short explanation of the magic behind:
There is a wrapper div around the images, that is given a width of 63px (in our case, which makes the box later on end up exactly with the date box next to it. You can choose any other size as well) and a height of 0. You guess it, the padding-bottom trick that helps us creating intrinsic ratios in CSS. You find a nice essence about this trick at Jonathan Nicol’s blog where I first found it (there are other ways, but this seems the only one nowadays that avoids using background-images and works in all modern browsers).
The image itself is then filling out the space by a height of 100% assigned to landscape and a width of 100% assigned to portrait formats. The other value is set to auto to not distort the image. The overlapping parts are cut off with the hidden overflow of the container div. The centering trick used here is based on a displacement of the image 50% to the left and top, setting the corner to the middle of the container, and then being placed back with the translate function. I consider this as true magic, and whoever figured out first as a true genious. According to my investigations the kudos go to Thierry Koblentz back into 2009. I feel blessed I could integrate it into my vision of a perfect calendar, also thanks to time.ly which prepared the code so wise.ly :)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
.ai1ec-agenda-view .ai1ec-event-header .ai1ec-event-avatar { display: inline-block; position: relative; overflow: hidden; width: 63px; height: 0; padding-bottom: 63px; } .ai1ec-agenda-view .ai1ec-event-header .ai1ec-event-avatar img { position: absolute; left: 50%; top: 50%; max-height: none; max-width: none; border-radius: 0; width: auto; height: 100%; -webkit-transform: translate(-50%,-50%); -ms-transform: translate(-50%,-50%); transform: translate(-50%,-50%); } .ai1ec-agenda-view .ai1ec-event-header .ai1ec-event-avatar.ai1ec-portrait img { height: auto; width: 100%; } |
Fine-tuning our output with CSS
Now that the image is set to its perfect size, we need to do some further CSS adjustments, otherwise the summary gets stuck as we see. The first CSS rule removes the bottom margin of our thumbnail, and together with the 63px chosen for our thumbnail size we achieve a perfect alignment of the header box with the date box. The second rule shows no visual difference, but the clickable area is expanded across the whole header height. The third CSS rule creates a bit more space to the summary to not be so clingy, and the fourth one places the event’s featured image to the right to not be exactly below its small thumbnail brother.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.ai1ec-agenda-view .ai1ec-event-header .ai1ec-event-avatar { margin-bottom: 0px; } .ai1ec-agenda-view .ai1ec-event .ai1ec-event-header { min-height: 63px; } .ai1ec-agenda-view .ai1ec-event-description { margin-top: 30px; } .ai1ec-agenda-view .ai1ec-event-summary .ai1ec-event-avatar { float: right; margin: 0px 0px 8px 16px; } |
Adding the categories’ colored dots to the box
Next I found the little colored dots appearing in the modal pop-ups of the widget, and I loved them, so I have put them to show in the third empty line of our agenda view. For this, we need to add this code right between the two DIVs that come before the {# Hidden summary, until clicked #}, in original line 54/55 (now around 64/65):
1 2 3 |
{% if event.category_colors %} <div class="ai1ec-color-swatches">{{ event.category_colors | raw }}</div> {% endif %} |
Some enhanced responsiveness
When we get to a small screen, the thumbnail messes up the text lines a bit, so below 567px we could take it out and also move the colored dots straight after the meta so they don’t take a whole single line for themselves anymore:
1 2 3 4 5 6 7 8 9 |
@media (max-width: 567px) { .ai1ec-agenda-view .ai1ec-event .ai1ec-event-meta, .ai1ec-agenda-view .ai1ec-event .ai1ec-color-swatches {display: inline} .ai1ec-agenda-view .ai1ec-event .ai1ec-event-title {display: block} .ai1ec-agenda-view .ai1ec-event-header .ai1ec-event-avatar {display: none;} } |
And that’s it so far. It will not stop here, but this was the main quest and I am very happy that I finally found my plugin. If you have questions or comments, drop them in the comments, and if you like the tutorial, please consider sharing.
Update 5.12.2015: Today the next part of the dream came true: All-in-One Event Calendar: Showing Categories or Tags in Tabs/Tabbed View
I have a problem I can’t seem to solve. Every time I update the plugin, I loose my custom theme. Have you figured a way around this?
Hello Adam, I didn’t loose my custom theme on update and the first idea would be to check if it is in its proper separate folder as described in the post or on the time.ly website. Where do you store it exactly?
Hi,
I’m a co-founder of Timely.. I would love to have a chat with you. Could you spare 8min sometime this or next week?
Sure, I wrote you a mail with my contact data…
Hi Sofian,
great tutorial thanks!
I have a small issue: when filter on category and/or tag is activated the new layout is lost whenever filter is changed.
1) apply your tutorial
2) show calendar with filter on category activated.
3) user change the categories to be visualized.
4) new agenda is displayed with “old” format .
:-(
Do you have any hints to avoid this?
When I created it, it worked, maybe through an update things changed and the code needs to be adapted. Can you send me your site where I can check it?
Hi,
it seems the issue is related to cache handling.
Clearing it and switching off the option “Use frontend rendering ” seems to solve the problem.
Thanks
Thanks for letting us know.
Thanks, now it works! :-)
wow! Great! Would you help me figuring out how to put the ticket button in the + of the calendar?Thanks!
Hi,
Enjoyed your article…. Do you write other blogs or articles on the All-in1 Event Calendar?
Thanks
Mel
Dear Mel, actually All-in-One changed its policy at a certain moment and restricted the free version to 20 events, which was leading me to tryout the Event Manager plugin, and what can I say, it became my new favorite because it is very flexible and I like its “personality” behind much more. So you will not see further All-in-One articles from me, but hopefully I find time to create a tutorial of what I got out of EM.
Hi,
Its been awhile since I read this post. I too am again looking for a new calendar program. I like the Events Manger also but the interface is horrible but it has many features…
Did you write any more articles on the Events Manager?
Thanks
Mel
Hey Mel, long time no see, and meanwhile a colleague of mine is fan of some DIVI specialized event plugins. We will within the next months together take a look at her experiences and choose one solution for our project’s website, if you remind me towards December I might have some recommendations to share by then.
Just gonna say a huge thank you! TWIG was an unexpected waltz I didn’t know I’d be taking at the start of this but it is pretty neat – I particularly needed to control the Featured image on the Agenda view so THANK YOU!
This is really great, just what I was looking for – thank you for sharing.
Is is possible to do something similar for the agenda-widget? I’ve had a play around with agenda-widget.twig without much luck.
Hi!!
I’ve some problems with google map. It’s not showed in the page. I only can see a block but not map.
I read from time.ly it need a php. code from theme’s footer but my theme have it so that I’ve no idea how to solve it.
Thanks in advance,
Thanks for sharing! Really enjoyed reading your article! :)
Thank you for your article. Very informative and easy to read. The thumbnail inclusion and css-beautification is a keeper. Like one of the other comments added, I too had some unexpected challenges … nah … problems understanding what this twig-stuff was about. A big thanks for this! I like that you deliver details for which file to edit – for example /wp-content/plugins/all-in-one-event-calendar/public/themes-ai1ec/vortex/twig – and not just write “blabla edit your twig-file”. Yes, but where is it? :)
A lot of other info on the net assumes that the reader knows what goes on – this is not necessarily so – and this makes your blog stand out.
I can see you moved on to another Event-plugin – but you helped me a lot with time.ly.