Events Manager conditional placeholders for custom attributes

The Events Manager plugin for WordPress is pretty flexible, allowing you to easily add custom attributes to your event posts. It also has conditional placeholders that allow you to display or hide information conditionally. There is a nice tutorial on the plugin website showing you how to add your own conditional placeholders. Lets bring this all together with a conditional placeholder for a custom attribute.

Let’s say we want to add an attribute called Website, with a link to a website promoting the event. We could add it to the list of attributes and then add the following snippet to our Single Event Page format in the Events Manager settings:

<p>
  <strong>Website</strong><br/>
  <a href="http://#_ATT{Website}" target="_blank">#_ATT{Website}</a>
</p>

The problem is that it will always show this on the event page, even when our Website attribute is empty. To hide that content when the attribute is empty, we need to add a conditional placeholder for it — let’s call it has_att_website (for “has attribute Website”). A simple regular expression will take care of removing our conditional placeholder without removing the content it surrounds, as you’ll see in the code below.

Conditional placeholders can actually do more than just hide or show content, they can change it. A very simple use of this is to take a chunk of text with line breaks in it, and convert those line breaks to BR tags using the handy nl2br() PHP function. So let’s add that to our placeholder code too!

Here’s the code, which can be added to a plugin or to a theme’s functions.php file.

[edit: {nl2br} is processed before placeholders, so I have changed it to call $EM_Event->output() on its contents to pick up placeholders too.]

/**
* add some conditional output conditions for Events Manager
* @param string $replacement
* @param string $condition
* @param string $match
* @param object $EM_Event
* @return string
*/
function filterEventOutputCondition($replacement, $condition, $match, $EM_Event){
    if (is_object($EM_Event)) {

        switch ($condition) {

            // replace LF with HTML line breaks
            case 'nl2br':
                // remove conditional
                $replacement = preg_replace('/\{\/?nl2br\}/', '', $match);
                // process any placeholders and replace LF
                $replacement = nl2br($EM_Event->output($replacement));
                break;

            // #_ATT{Website}
            case 'has_att_website':
                if (is_array($EM_Event->event_attributes) && !empty($EM_Event->event_attributes['Website']))
                    $replacement = preg_replace('/\{\/?has_att_website\}/', '', $match);
                else
                    $replacement = '';
                break;

        }

    }

    return $replacement;
}

add_filter('em_event_output_condition', 'filterEventOutputCondition', 10, 4);

Now, we can change our Single Event Page format to make use of the conditional placeholder.

{has_att_website}
<p>
  <strong>Website</strong><br/>
  <a href="http://#_ATT{Website}" target="_blank">#_ATT{Website}</a>
</p>
{/has_att_website}

<p><strong>Something with line breaks</strong>
{nl2br}
#_ATT{Something with line breaks}
{/nl2br}
</p>

There, job is done if and when we want it.

Facebooktwittergoogle_plusredditlinkedinmailFacebooktwittergoogle_plusredditlinkedinmail
  • That worked nicely. The Event Manager plugin doesn’t come with a way to say that an event’s date has not yet been announced. But my client still wanted to advertise the course on their website and start signing people up.

    First I set up an attribute called TBA (to be announced).

    Then set up two new functions:
    1) has_att_tba (so I can display a message)
    2) has_no_att_tba (so I can hide the date)

    Here’s the code I used to display a message in lists and single events:

    {has_att_tba}
    #_ATT{TBA}
    {/has_att_tba}
    {has_no_att_tba}
    #j #M #Y #@_{ — j M Y}
    {/has_no_att_tba}

    • Excellent, well done. Events Manager doesn’t cater for all occasions right out of the box, but it certainly is flexible enough. I’ve been fighting with a few other plugins that don’t let you hook into them the way Events Manager does, and it makes a real difference.

  • Thanks for the post, your instruction is far clearer then the official documentation. But I just can’t get it to work.

    I have this in the functions.php:

    function filterEventOutputCondition($replacement, $condition, $match, $EM_Event){
    if (is_object($EM_Event)) {
    switch ($condition) {
    // #_ATT{Premium}
    case 'has_att_premium':
    if (is_array($EM_Event->event_attributes) && !empty($EM_Event->event_attributes['Premium']))
    $replacement = preg_replace('/{/?has_att_premium}/', '', $match);
    else
    $replacement = '';
    break;
    }
    }
    return $replacement;
    }
    add_filter('em_event_output_condition', 'filterEventOutputCondition', 10, 4);

    And I have this within the ‘Default event list format’:

    #_ATT{Premium}
    {has_att_premium}
    #_ATT{Premium}
    More
    {/has_att_premium}

    NB: the ‘hideMe’ class will be set to display:none; as I don’t want the new attibute display, it’s only purpose is to show/side the #_EVENTURL.

    The attribute does display when set, but the conditional statement doesn’t show when the attribute is set.

    Any thoughts?

    • G’day Tony,

      I can’t spot a problem, looking at your code. When you say “the conditional statement doesn’t show”, what do you actually get in your output? Can you be sure that your function is actually being called?

      e.g. for a quick test, change the last line to “return ‘filterEventOutputCondition’;” and it should write that function name all over the event if the function is being called.

      Also, if you turn on debugging (edit your wp-config.php file and change WP_DEBUG to true), does it give you any errors? NB: you might find that experience somewhat frightening, some plugins throw lots of warnings and errors!

  • The second block of code should read as:

    http://pastebin.com/hzZi5d77

  • Thanks for getting back to me.

    I mean that where it should output the code within the conditional statement if it were true and being called there is nothing being shown within the front end source code. So it may not actually be being called. It displays the attribute that I have included outside of the conditional statement (to test that the attribute is being set).

    Do you mean replace:
    return $replacement;
    with:
    return “filterEventOutputCondition”;
    If so nothing happens.

    I an new to EM so I might have missed an obvious setting somewhere?

    Regards debug.

    In backend I get:

    Notice: load_plugin_textdomain was called with an argument that is deprecated since version 2.7 with no alternative available. in ………../wp-includes/functions.php on line 3553

    Notice: has_cap was called with an argument that is deprecated since version 2.0! Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead. in ………../wp-includes/functions.php on line 3551

    In frontend I only get:

    Notice: load_plugin_textdomain was called with an argument that is deprecated since version 2.7 with no alternative available. in ……./wp-includes/functions.php on line 3553

    • G’day Tony, the debug messages just mean that a plugin or theme you’re using is using old parameters when calling some WP functions; nothing to worry about there.

      Now, I suspect you might be putting this code in the wrong file. I copied your code exactly, and pasted it into the bottom of the functions.php file in my active theme — i.e.

      /wp-content/themes/my-theme/functions.php

      and it worked as advertised. What file are you putting this code into?

      Also, have you ticked yes on Enable event attributes? in the General Options?

  • Thanks for getting back to me.

    It’s going at the bottom of my my themes function.php file:
    http://pastebin.com/2FncBeiM

    Might it conflict with something else?

    And yes ‘Enable event attributes’ is checked. The new attribute is being set as I have included the attribute outside of the conditional statement to check that it is being set.

    It would be so much easier if you could include php code within the Setting>Layout>Formatting for the plug in.

    • Did you mean functions.php or did you actually put it into function.php?

  • I meant functions.php.

    I have just added it to the Twenty Eleven functions.php file and it it working so it is something on my theme. I will see if I can figure that one out….

    • Doh!

      I think it was down to a missing ‘;’ in a previous function. All working now, thanks for the input, helped me look at the problem from a different angle.

      • Well done, nice to hear it was a happy ending :)

        cheers,
        Ross

  • Dan

    Hi there,

    I was just wondering if there is a way to use multiple attributes as in: has_att_this or has_att_that. I have a few different prices which work great using conditional placeholders individually but I also want to be able to get rid of all prices when the venue is closed some weeks.

    Any ideas?

    • G’day Dan, you can create a conditional placeholder that tests for any condition, be it a simple one-attribute test or more complex multi-attribute logic. So if you want to test whether either one or another attribute has a value, you can make one placeholder that does both tests. But for the example you mention, you probably just need a placeholder that tests that the venue is not closed, and wrap that around the prices.

      cheers,
      Ross

  • Sam Blowes

    Im using the NL2BR function like so:
    {nl2br}#_EVENTEXCERPT{/nl2br}

    And im echoing the result to check it:

    case 'nl2br':
    $replacement = nl2br(preg_replace('/{/?nl2br}/', '', $match));
    echo $replacement;
    break;

    And it reurns: #_EVENTEXCERPT

    What am I doing wrong?

    • G’day Sam,

      The problem was that conditional placeholders are processed before “regular” placeholders, so #_EVENTEXCERPT wasn’t being replaced until after the {nl2br} replacement. I’ve changed the code above to process the contents of {nl2br} before calling nl2br(), so please update your code.

      cheers,
      Ross

  • Kelly Andrews

    This code saved my life – dropped it in, edited a bit, good to go. Thanks!

  • When I use the listed code it results in a error of

    “Parse error: syntax error, unexpected ‘{‘ in /home/crew505/public_html/dev/wp-content/themes/Venturing Crew 505/functions.php on line 11”

    line 11 includes the following code:
    if (is_object($EM_Event)) {

    Code is currently being placed in a child theme functions.php file.

    Please help

    • Issue resolved

      • I’m glad you resolved your issue; sorry I wasn’t around to help (it was sleepy bye time here in Australia!)

        cheers,
        Ross

  • Hello,
    Thank you for this helpful code and explanation. I added an attribute ‘higlights’ and this code to the function:
    ———–
    case 'has_att_highlights':
    if (is_array($EM_Event->event_attributes) && !empty($EM_Event->event_attributes['highlights']))
    $replacement = preg_replace('/{/?has_att_highlights}/', '', $match);

    else
    $replacement = '';
    break;

    ——-
    In the page this works beautifully:

    #_ATT{highlights}
    {has_att_highlights}We'll be at: #_ATT{highlights}{/has_att_highlights}

    but this does not:

    {has_att_highlights}We'll be at: #_ATT{highlights}{/has_att_highlights}

    does the #_ATT{highlights} need to be initialized in some way before calling the function? It is inside a [events_list recurring="1" orderby="event_name"] loop.

    Thank you so much!

    • G’day Brittney,

      You need to separate the conditional statements from the attribute, due to some issue with the way Events Manager handles those two things. This works with your code above:

      {has_att_highlights}
      We'll be at: #_ATT{highlights}
      {/has_att_highlights}

      cheers,
      Ross

  • Thank you! That worked. Thought I was going crazy because it was working at some point. Your code is a great help, I appreciate it.

  • One more question, how can I create a conditional for a custom attribute for that event’s location? For example, my locations have a custom attribute ‘tips’, would I use something like this to check if this event’s location has ‘tips’:

    if (is_array($EM_Event->location->attributes) && !empty($EM_Event->location->attributes[‘tips’]))
    or
    if (is_array($EM_Event->location_attributes) && !empty($EM_Event->location_attributes[‘tips’]))

    Thanks!
    Brittney

    • G’day Brittney,

      Assuming that you’re still talking about the single event (and its location), you can create a location attribute (#_LATT{}) and this code will pick up the non-empty ones one a single event:


      case 'has_latt_loctest':
      if (isset($EM_Event->location) && !empty($EM_Event->location->location_attributes['loctest']))
      $replacement = preg_replace('/{/?has_latt_loctest}/', '', $match);
      else
      $replacement = '';
      break;

      NB: if you mean a single location view, you’ll need to use a different filter hook: em_location_output_condition is the equivalent.

      cheers,
      Ross

      • Hello, I assume this also means all instances of

        $EM_Event->event_attributes

        Need to change to

        $EM_Event->location->location_attributes

        Is this correct? I want to modify the code in this article to apply to locations, not events. Thanks.

        • Yes, if you’re accessing location attributes from the em_event_output_condition hook. If you’re using the em_location_output_condition hook, you’ll get an EM_Location object instead of an EM_Event object.

          cheers,
          Ross

  • works perfectly! thanks again.
    Brittney

  • Hi!
    I’ve an attribute like this:

    #_ATT{Link vendita ticket online}

    and your function seems not working..

    Do you have any hints for me?

    Thank you

    Dimitri Grassi

    • G’day Dimitri,

      In the code above, you should be replacing ‘has_att_website’ with something like ‘has_link_vendita_ticket_online’ or similar — with no spaces — which you’d then use like this:

      {has_link_vendita_ticket_online}
      <p>
      <strong>Website</strong><br/>
      <a href="http://#_ATT{Link vendita ticket online}" target="_blank" rel="nofollow">#_ATT{Link vendita ticket online}</a>
      </p>
      {/has_link_vendita_ticket_online}

      cheers,
      Ross

  • AJD

    Hello! Thanks for this great tutorial on conditional placeholders for Events Manager.
    I tried to use your version to check when a custom ATT is empty instead of when it is filled in, but for some reason it didn’t work. It kept displaying the ‘{no_message}’ markup.

    Here is what is working:


    function my_em_has_attribute_event_output_condition($replacement, $condition, $match, $EM_Event){
    if( is_object($EM_Event) && preg_match('/^no_message$/', $condition,$matches) ){
    if( !in_array($args['feat_message'],$EM_Event->event_attributes)
    && empty($EM_Event->event_attributes['feat_message']) ){
    $replacement = preg_replace("/\{\/?$condition\}/", '', $match);
    }else{
    $replacement = '';
    }
    }
    return $replacement;
    }
    add_action('em_event_output_condition', 'my_em_has_attribute_event_output_condition', 1, 4);

    ////////////// Usage:

    [events_list]
    #_EVENTLINK
    #_ATT{feat_message}
    {no_message}
    This displays when the feat_message ATT is not set.
    {/no_message}
    [/events_list]
    /////////////

  • Mimmo Melissa

    How can I change code for locations page?
    For events page I use:

    // SHOW PRICE
    function my_em_has_attribute_event_output_condition($replacement, $condition, $match, $EM_Event){
    if( is_object($EM_Event) && preg_match(‘/^show_price$/’, $condition,$matches) ){
    if( !in_array($args[‘price’],$EM_Event->event_attributes) && ($EM_Event->event_attributes[‘price’]) ){
    $replacement = preg_replace(“/{/?$condition}/”, ”, $match);
    }else{
    $replacement = ”;
    }
    }
    return $replacement;
    }
    add_action(’em_event_output_condition’, ‘my_em_has_attribute_event_output_condition’, 1, 4);

  • Tako van Midwoud

    Great tutorial! But unfortunately it doesn’t seems to work. This is the code I use:

    function filterEventOutputCondition($replacement, $condition, $match, $EM_Event){
    if (is_object($EM_Event)) {
    switch ($condition) {
    // #_ATT{Mobiel}
    case 'has_att_mobiel':
    if (is_array($EM_Event->event_attributes) && !empty($EM_Event->event_attributes['Mobiel']))
    $replacement = preg_replace('/{/?has_att_mobiel}/', '', $match);
    else
    $replacement = '';
    break;
    }
    }
    return $replacement;
    }
    add_filter('em_event_output_condition', 'filterEventOutputCondition', 10, 4);

    And this in the ‘Default event list format’:

    <p>
    <strong>Contact</strong><br/>
    #_ATT{Contactpersoon}<br/>
    #_ATT{Telefoon}<br/>
    {has_att_mobiel}
    #_ATT{Mobiel}<br/>
    {/has_att_mobiel}
    #_ATT{E-mail}<br/>
    <a href="http://#_ATT{Website}" target="_blank">#_ATT{Website}</a>
    </p>

    When I use this code, this error wil show up on the top of my page:

    Warning: preg_replace() [function.preg-replace]: Unknown modifier '?' in /public/sites/www.weekvandebegraafplaats.nl/wp-content/themes/weekvandebegraafplaats/functions.php on line 43

    What am I doing wrong? Hope you can help me.

    • G’day Tako,

      My apologies, somehow (perhaps when I moved this blog into a multisite) some backslashes went missing. Look again :)

      • Tako van Midwoud

        Awesome! Thanks for your help, you saved me. :D

  • GaetanAsselberghs

    Is it possible to render the H (hour) in the next statement:

    {is_long}#D #d #M from #H:#i until #@H:#@i{/is_long}
    {not_long}#D #d #M from #H:#i until #@H:#@i{/not_long}

    As H+2 ?? What would be the syntax of such a statement?

    (An event from 19:00 untill 22:00 would render in single event page as: from 21:00 until 24:00)

    Thanx for any help!

    • You probably should be asking that on the support forum.

      • GaetanAsselberghs

        I did, but to no response yet, but this site/thread seems to be populated with people with knowledge about the subject #dare to ask.

  • Works great, thanks!

  • Luis

    Could i turn the above code into a conditional whereas a multiple day event would display an end date after the initial Start date?

    Thanks

  • axel

    What do i need to do when i want to use this code for a second att

  • johanisk

    Thanks! I can’t quite get it to work though. I have an attribute called ‘courts’

    I have added this to the functions file:

    function filterEventOutputCondition($replacement, $condition, $match, $EM_Event){

    if (is_object($EM_Event)) {

    switch ($condition) {

    // #_ATT{courts}

    case ‘has_att_courts’:

    if (is_array($EM_Event->event_attributes) && !empty($EM_Event->event_attributes[‘courts’]))

    $replacement = preg_replace(‘/{/?has_att_courts}/’, ”, $match);

    else

    $replacement = ”;

    break;

    }

    }

    return $replacement;

    }

    add_filter(’em_event_output_condition’, ‘filterEventOutputCondition’, 10, 4);

    and this to my event listing:

    {has_att_courts}No more than #_ATT{courts} courts in use.{/has_att_courts}

  • chictype

    Hello,

    if event attribut name contain space, it ‘s not working
    (exemple : $EM_Event->event_attributes[‘your web site’] into function with #_ATT{your web site} into param of an event page won’t work)

    Can’t change the name of the attribute because it is what the user use in the event form

    Do you have a solution ?

    • Beee

      I also have spaces, but for me it does work… just edited all my placeholders into the code above…

  • Kirsten

    Hi there! This worked great. However, I’d like to have the Event Title in the $replacement = ” string. What is the Event Manager php for that?

    In otherwords, it shows the att_website, OR it shows the Event Title alone.

    My guess is that I’d do something like:
    {has_no_att_website} and create that conditional formatting… but what is the PHP to output into the functions.php?

  • STAVROS CHALARIS

    Can I have reach text editor?
    I would like to add tags as br, strong etc.
    How can I do this?

  • playmobil

    Hi,
    First of all, thanks for the great work!
    I am able to make it work for a conditional attribute, but what I want to achieve is to make a conditional placeholder for each pre-defined attribute value.
    If my att is something like #_ATT{style}{A|B|C}, how can I create 3 placeholders like {has_att_style_A}, {has_att_style_B}, {has_att_style_C}?
    What would be the right syntax? Is it possible to do so?
    As said, thanks!

  • Teresa Nightingale

    This is great, thanks!
    My events have quite a few custom attributes though. Do I have to create a conditional placeholder for each one (website, email, pet policy, etc. etc.)? Could there be a generic one that works for any empty attribute? e.g. something like {has_a_value} that could be used many times within the single event page format?

    • G’day Teresa, I think you will need a conditional placeholder for each one. You could be clever and write some generic code to handle that (e.g. test for placeholder starts with ‘has_att_custom_’ and then uses the rest of the string as the attribute name) but that could cause problems with special cases so I’d advise against it; go simple and be successful. You should ask in the EM support forum for a definitive answer though.

      cheers,
      Ross

  • D. Ch.

    Hi. As might do the same, hide a variable as the website, but Locations? Event works, but I would need to do so in locations. Thank you.