Update 24th June 2019

Hi all. I recently revamped my website and in the transfer forgot to include the files and some images for this post. Basically, I decided to put my blog on hold for a while and I didn’t pay it much attention during the redesign.

However, this post does get a lot of hits, so I have placed the code now in GitHub and provided the links.

My apologies to everyone.

The Events Calendar Pro and Event Tickets Plus are very popular plugins from the people at Modern Tribe. I have used these products extensively on one of my clients website and these plugins helped enable us to develop a website which has increased my clients sales by more than 30%. My client loves it and so do her customers. You can find the site at https://ashdowncookeryschool.co.uk.

Suffice it to say that getting to grips with these plugins can be quite a learning curve, but with so many features available I guess it should not be a surprise and I have always found the support team at the help desk very knowledgeable and willing to help where they can. The one area where they are understandably unable to provide detailed help is with custom coding.

There are fairly consistent requests from users in the support forums for help to customise the ‘Photo’ View which is a Pro feature and it certainly was at the top of mine and my clients list to produce a more ‘grid’ like view, with consistent heights for the events. In addition I wanted to add the ticketing information which comes as standard in the ‘List’ view, but does not in the ‘Photo’ view. The aim was to use the ‘Photo’ view as the default view and to provide a consistent user experience across ‘Photo’ and ‘List’.

The images below show the view you can expect as standard, the one on the right is where I ended up.

Photo View ‘Out of the Box’

Photo View ‘Custom’

The steps to achieve this custom view I worked out by myself with help from the Support Desk, the Modern Tribe Knowledge Base and applying the use of Action and Filters in WordPress. I daresay there are better ways to do this, but this has worked for me.

The bottom line is that these plugins are very easy to customise as Modern Tribe do provide a lot of Hooks that allow you to tinker to your hearts content.

As always, take a backup of your website before trying this and better still work on a staging site first until you are confident about what you are doing.

At the time of writing the Modern Tribe plugins were at the following versions on my site,

The Events Calendar v 4.6.10.1

The Events Calendar Pro v 4.4.22

Event Tickets v 4.6.3

Event Tickets Plus v 4.6.2

The single-event.php file from ‘Photo’ view we use later was a v 4.4.8

Please remember that hooks and functions can change, so keep an eye on any deprecation’s that Modern Tribe may announce in their revision documentation.

So without further ado, here are the steps we will take to create this view,

  1. Create the Child structure required.
  2. Add the code to display the ticket price and display the number of tickets available.
  3. Change the excerpt to display fewer words.
  4. Add a ‘Read More’ link.
  5. Add CSS to style.
  6. Add the code to change ‘Photo’ to ‘Grid’ and ‘Tickets’ to ‘Places’.

1. Create the Child structure

Using your FTP client (I use FileZilla) create the following directory structure in your themes Child folder. I am using Divi by Elegant Themes, so I have;

wp-content / themes / divi-child / tribe-events / pro / photo

Now go look at your wp-content / plugins directory and look for ‘events-calendar-pro’. Open it up and inside you will see a folder called ‘src’ , open it up. Now you are looking for the ‘views’ directory, open this up as well. In here you will see the directory ‘pro’ , open this up. In ‘pro’ you will see another directory called ‘photo’ and in here (phew!! we got there !!) you will see the file we need which is ‘single-event.php’.  This is the file we want to copy to our child folder ‘photo’ (see above).

In summary, the file can be found at,

wp-content / plugins / events-calendar-pro / src / views / pro / photo / single-event.php

Now copy that file to your child structure so we have,

wp-content / themes / divi-child / tribe-events / pro / photo / single-event.php

Oh, and incidentally you will need to have created a functions.php file in your child directory and enqueued your style sheet. If you do not know how to do this, then there are many sources on the web you can find to easily help you do this. So mine sits in,

wp-content / themes / divi-child /  directory.

Now, let us check first that the above steps have been done correctly shall we? before we do anymore real work.

Open up the single-event.php file you have just copied into your child directory and in the first few lines you will see the following,

<?php
/**
* Photo View Single Event
* This file contains one event in the photo view
*
* Override this template in your own theme by creating a file at [your-theme]/tribe-events/pro/photo/single-event.php
*
* @package TribeEventsCalendar
* @version 4.4.8
*/

if ( ! defined( ‘ABSPATH’ ) ) {
die( ‘-1’ );
} ?>

<?php

global $post;

?>

Now, between <?php and global $post;  type in the following,

echo “Hello World<br />” ;

Now save the file and refresh your page and you should see Hello World printed on top of each event.
Now delete the line of code we just added and we can move onto the next stage.

2. Add the code to display the ticket price and the number of tickets available.

To get the price displayed we need to simply echo the function that is used in the ‘list’ view, which is the ‘tribe_get_cost” function. We simply decide where we want to place it in the content order and then add it in. I decided I wanted to add it after the event title. You will see this in a minute.

The code we need to display the number of tickets and emulate what is seen in ‘List’ view is a  do_action hook provided by Modern Tribe that displays the ticketing information and buy now button.

do_action(‘tribe_events_inside_cost’)

in addition to this, we add a couple of our own classes  so that we can target them later with our CSS. The code block looks like this,

<span class=”jp-tribe-events-cost”> <?php echo tribe_get_cost( null, true ); ?></span>
                <h2 class=”jp-tribe-events-from-list”><?php
        do_action( ‘tribe_events_inside_cost’ )
        ?>
Note I have used a unique prefix for the class names, in my case ‘jp-‘ so that there is little chance of future plugin updates including a new class that could conflict.
I have placed the code within the <a></a> tag so that where ever the user clicks in that area, they will get through to the actual event.
Here is what single-event.php now looks like, our new code block is the red text.

<?php
/**
* Photo View Single Event
* This file contains one event in the photo view
*
* Override this template in your own theme by creating a file at [your-theme]/tribe-events/pro/photo/single-event.php
*
* @package TribeEventsCalendar
* @version 4.4.8
*/

if ( ! defined( ‘ABSPATH’ ) ) {
die( ‘-1’ );
} ?>

<?php

global $post;

?>

<div class=”tribe-events-photo-event-wrap”>

<?php echo tribe_event_featured_image( null, ‘medium’ ); ?>

<div class=”tribe-events-event-details tribe-clearfix”>

<!– Event Title –>
<?php do_action( ‘tribe_events_before_the_event_title’ ); ?>
<h2 class=”tribe-events-list-event-title”>
<a class=”tribe-event-url” href=”<?php echo esc_url( tribe_get_event_link() ); ?>” title=”<?php the_title() ?>” rel=”bookmark”>
<?php the_title(); ?>
</h2>
<span class=”jp-tribe-events-cost”> <?php echo tribe_get_cost( null, true ); ?></span>
<h2 class=”jp-tribe-events-from-list”><?php
do_action( ‘tribe_events_inside_cost’ )
?>
</a>
</h2>
<?php do_action( ‘tribe_events_after_the_event_title’ ); ?>

<!– Event Meta –>
<?php do_action( ‘tribe_events_before_the_meta’ ); ?>
<div class=”tribe-events-event-meta”>
<div class=”tribe-event-schedule-details”>
<?php if ( ! empty( $post->distance ) ) : ?>
<strong>[<?php echo tribe_get_distance_with_unit( $post->distance ); ?>]</strong>
<?php endif; ?>
<?php echo tribe_events_event_schedule_details(); ?>
</div>
</div><!– .tribe-events-event-meta –>
<?php do_action( ‘tribe_events_after_the_meta’ ); ?>

<!– Event Content –>
<?php do_action( ‘tribe_events_before_the_content’ ); ?>
<div class=”tribe-events-list-photo-description tribe-events-content”>
<?php echo tribe_events_get_the_excerpt() ?>
</div>
<?php do_action( ‘tribe_events_after_the_content’ ) ?>

</div><!– /.tribe-events-event-details –>

</div><!– /.tribe-events-photo-event-wrap –>

There is a button below to get you access to all the code later.

The output of this will also display the ‘Buy Now’ button, which I did not want. So the following CSS got rid of this,

.tribe-events-list .tribe-events-photo-event .tribe-button {
display: none !important;
}
BTW To remove the button in the List view I also had to add,
.tribe-events-event-cost .tribe-button {
display: none !important;
}
You should now see the following view. Please note I have used our new classes to add some colour to our new information. You can adapt to your own needs. e.g.
.tribe-events-photo-event h2.jp-tribe-events-from-list {
font-size: 1.2em;
color: #8cabab;
}
#tribe-events .tribe-events-list .tribe-events-event-cost span {
font-style: normal !important;
}
.tribe-events-photo-event span.jp-tribe-events-cost {
font-size: 1.2em;
font-weight: 700;
padding-left: 5px;
}
but we will deal with the full CSS needs later.

3. Change the excerpt to display fewer words

Now the excerpt shown in Photo View is rather lengthy and in my opinion the user does not want to see this at this stage of their shopping experience. They want to get a general idea of what the course/ event is called, the date, price and if there are tickets left. Once they have made an informed choice, they will then want to click to read more detail and book a place.

In addition, if we want to end up with a fixed height for the event container, then we need to get very specific about how much content is displayed. So let’s see how we do this.

The first step is to open your functions.php file in you theme child folder and add the following code snippet,

function word_count($string, $limit) {

$words = explode(‘ ‘, $string);

return implode(‘ ‘, array_slice($words, 0, $limit));

}

Now let’s open our single-event.php file again and around line 60, towards the end, you will see the comment

<!– Event Content –>

look just below this for the code,

<?php echo tribe_events_get_the_excerpt() ?>
and replace this with,
<?php echo word_count(get_the_excerpt(), ’15’) . ‘…’;  ?>
the code above sets the number of words to 15 and concatenates a … at the end. Therefore to adjust the number of words, change 15 to something that suits you.

 

 

 

4. Add a ‘Read More’ link

You do not necessarily need this of course, as links to the event are included in the image, the title and now the price and ticket number. For mobile views I do not use this, but for desktop it was something my client wanted, so here it is.

Open your single-event.php file again from your child folder and at the bottom under the section

<!– Event Content –>
you should have the following code , our replacement code from step 3. is highlighted in red.
<?php do_action( ‘tribe_events_before_the_content’ ); ?>
<div class=”tribe-events-list-photo-description tribe-events-content”>
<?php echo word_count(get_the_excerpt(), ’15’) . ‘…’;  ?>
</div>
<?php do_action( ‘tribe_events_after_the_content’ ) ?>
We will now add code to get us the ‘Read More’ link and the final result would be (again, our new code is in red).
 <!– Event Content –>
<?php do_action( ‘tribe_events_before_the_content’ ); ?>
<div class=”tribe-events-list-photo-description tribe-events-content”>
<?php echo word_count(get_the_excerpt(), ’15’) . ‘…’;  ?>
</div>
<div class=”tribe-events-list-event-title-book”>
<a class=”url” href=”<?php echo esc_url( tribe_get_event_link() ); ?>” title=”<?php the_title() ?>” rel=”bookmark”>
<?php echo “Read more…”;?>
</a>
</div>
<?php do_action( ‘tribe_events_after_the_content’ ) ?>
You should now see the following,
Click on the button below to get the full and custom single-event file.  Copy it into your text editor and save as single-event.php

5. Add CSS to style

a) set the container height for the event to a fixed amount,

.tribe-events-list .tribe-events-photo-event .tribe-events-event-details {
height: 270px;
}
Note: this will need to be adjusted for different devices in your media queries. This might mean increasing the container height, reducing the text size, or a mixture of both.
b) Let’s anchor the Read more… link to the bottom of the container by 15px  for a consistent aligned view and provide some styling. (note: the duck egg blue I am achieving is being inherited from the Divi link global settings. So you may need to add a line here to provide your own font colour. (notice we are using the class we created in our single-event.php file to provide good targeting.)
.tribe-events-list .tribe-events-photo-event .tribe-events-list-event-title-book {
position: absolute;
bottom: 15px;
left: 15px;
width: 50%!important;
font-weight: 500;
font-size: 1.2em;
For mobile devices I use a media query which removes the Read More link.
c) Important notes to remember.
Depending upon your website and title lengths what you will see happen on smaller screens is that the price wraps around into the next line on some but not all events. This can make things look ugly. Therefore in the media query, I add a display: block to the price, so that it is always below the title and not to the right. This means you can style things more consistently in tablets and mobile devices  e.g.
@media only screen and (max-width: 1024px) {
.tribe-events-photo-event span.jp-tribe-events-cost {
display: block;
padding-left: 0px;
}
Click the button below to see the full CSS. Save to your theme child folder as css.style
A VERY IMPORTANT thing to remember is that the Tribe Photo View is programmed to work in the same way that say Pinterest displays. So , a rather jaunty style that steps the events and not always in date order.  If you want to keep your new Photo/ Grid stlye displaying events in date order then you HAVE to make sure that every image used is exactly the same size. I use 600px x 400px and even 1px difference will move the events around in a way you did not want.
Hopefully by now you have the following view,

6. Code for changing some of the labels.

So, will have noticed that I have replaced the words ‘ticket(s)’ with ‘place(s’) and ‘Photo’ is now ‘Grid’.

Here are the code snippets to do this. Simply add them to your functions.php file in your themes child folder.

Ticket(s) to Place(s)

function changes_button_text( $html ) {

$html = str_replace(“tickets left”, “places left”, $html);
$html = str_replace(“ticket left”, “place left”, $html);
return $html;
}

Photo to Grid  (I also changed the label for the Calendar here from ‘Month’ to ‘Calendar’, delete this line if you do not need it).

function tribe_custom_theme_text ( $translations, $text, $domain ) {

$custom_text = array(
‘Tickets’ => ‘Please select the number of places you require’,
‘Photo’ => ‘Grid’,
‘Month’ => ‘Calendar’,
‘Related %s’ => ‘Similar %s’,
);

// If this text domain starts with “tribe-” or “the-events-“, and we have replacement text
if((strpos($domain, ‘tribe-‘) === 0 || strpos($domain, ‘the-events-‘) === 0 || strpos($domain, ‘event-‘) === 0) && array_key_exists($text, $custom_text) ) {
$text = $custom_text[$text];
}

return $text;
}
add_filter(‘gettext’, ‘tribe_custom_theme_text’, 20, 3);

Click below to get all the code we added to the functions.php file during this tutorial. I have also included the code to change ‘Event’ to ‘Course’ and ‘Events’ to  ‘Courses’. Copy it into your editor and save as functions.php in your child theme folder.
That’s the end ! I know it was a long process, but hopefully you got a lot out of it.