• Resolved KlausFriese

    (@klausfriese)


    Hi,

    I’m just working on the integration of the ICS Calender, great plugin, works fine.

    On our page I like to show a text like “Next event: Super party on *date*” on the top of the page and the calender with all events below.

    My idea to realize this was to filter the ICS data by using r34ics_display_calendar_filter_ics_data and saved the next event to a global variable. And to display that global variable in an function called by a new shortcode [nextevent] I made.
    This works fine if my [nextevent] is placed AFTER the [ics_calender ..]. If I put the [nextevent] before the calender it doesn’t work – the filter is only called when a calender is displayed.

    My question is: Can I call the r34ics_display_calendar_filter_ics_data without displaying a calender? Or can I use the [ics_calender ..] with a kind of “view=’none'” parameter?

    Thanks
    KLaus

Viewing 8 replies - 1 through 8 (of 8 total)
  • Plugin Author room34

    (@room34)

    Unfortunately that won’t work, because the calendar data is not loaded until the shortcode runs.

    I have a suggestion that will probably work, but it’s convoluted and inefficient.

    At the point where you want to run the filter, you should first do this:

    ob_start();
    do_shortcode('[ics_calendar …]');
    add_filter('r34ics_display_calendar_filter_ics_data', 'YOUR_FILTER_FUNCTION');
    $ics_calendar_output = ob_get_clean();

    Replace the … with the rest of your actual calendar shortcode and YOUR_FILTER_FUNCTION with the name of your function, or a closure if you want to do it that way.

    The last line is putting the calendar output into a variable instead of just discarding it, so you could echo that variable in your template instead of actually calling the shortcode a second time in your content, but as long as your shortcode is exactly the same and doesn’t include reload="true" then the parsed data will be cached so it shouldn’t impact performance significantly to include the shortcode again directly in your page content. But keep in mind your filter will run again too. (It will end up with the exact same value, but whatever processing it does will be repeated, which could affect performance.)

    Plugin Author room34

    (@room34)

    One thing I would add/emphasize… this is not a good way to do this, it’s just something I think should work, given the context and the available tools in ICS Calendar.

    What you really need is a utility function that does all of this calendar parsing without actually generating the output. Unfortunately as the plugin currently functions, the parsing is built directly into the method that generates the output. But I could look into moving that into a separate method that just returns the $ics_data array. I would also then need to set up a way to cache that data so the R34ICS::display_calendar() method (the one that currently does the parsing and generates the output HTML) could use it instead of parsing the feed again. Sounds like a good refactoring project for a future update.

    Thread Starter KlausFriese

    (@klausfriese)

    Thanks a lot, I will try that. And moving the parsing to a separate function is a good idea for a future version.

    Another idea I had: I class-r34ics.php there’s a switch for the view and the default call a filter or an action. Filters for setting the date range and an action r34ics_display_calendar_render_template
    Can I use these?

    Plugin Author room34

    (@room34)

    All of those filters are available for use… they’re in there to hook in the additional capabilities of the Pro version, so they’re definitely not going away. I’m still in the process of adding documentation for them in the User Guide.

    Thread Starter KlausFriese

    (@klausfriese)

    I tried:

    add_action( 'r34ics_display_calendar_before_render_template', 'loadICSdata' );
    
    // The action callback function.
    function loadICSdata( $view, $args, $ics_data ) {
    	// do something
    }
    
    add_filter('r34ics_display_calendar_set_first_date', function($view, $first_date, $startdate, $pastdays) {
    	// do something    
    	return $something;
    } );
    
    add_filter('r34ics_display_calendar_set_limit_date', function($view, $first_ts, $limitdays) {
    	// do something    
    	return $something;
    } );
    
    add_filter('r34ics_display_calendar_set_earliest', function( $view, $first_date) {
    	// do something    
    	return $something;
    } );
    
    add_filter('r34ics_display_calendar_set_latest', function( $view, $limit_date, $first_ts, $limitdays, $limitdayscustom) {
    	// do something    
    	return $something;
    } );
    

    The action r34ics_display_calendar_before_render_template is called, but the $ics_data[‘events’] is empty. Filters are not called – what’s can be wrong here?

    Thanks
    Klaus

    Plugin Author room34

    (@room34)

    I’m not sure what you’re intending to do with those date range filters; they’re really intended for use in creating custom view templates (again, specifically created for Pro to have its own additional templates).

    As for r34ics_display_calendar_before_render_template, that’s an action intended to allow creation of custom output prior to displaying the calendar. It’s not really the ideal place for manipulating the content of the $ics_data variable; it’s better to use the r34ics_display_calendar_filter_ics_data filter for that.

    Were you using the aforementioned date range filters to set a date range? If those are used incorrectly, there won’t be any valid date range and the $ics_data array will be empty.

    At this point we’re getting well outside the intended use of these hooks and the plugin in general, so I’d need more specifics of what you’re trying to do (i.e. the exact code you’re running) to be able to offer any guidance.

    Plugin Author room34

    (@room34)

    I have an update for you on this. Version 8.12.0, which is on its way to the repository right now, adds a new function: r34ics_get_ics_data(). This runs the R34ICS::display_calendar() method without actually outputting the template display, and instead simply returns the fully parsed $ics_data array.

    You should use this function instead of my initial suggestion of output buffering the shortcode and tapping into the filters as it runs. You may still want/need to use some of the filters; they all still get applied when this function runs — up to and including r34ics_display_calendar_filter_ics_data.

    The function accepts an array as input, which should contain key-value pairs matching the attributes you would use in your shortcode. For example:

    $ics_data = r34ics_get_ics_data(array(
        'debug' => 2,
        'limitdays' => 455,
        'pastdays' => 90,
        'url' => 'https://example.com/calendar.ics',
        'view' => 'month',
    ));

    Note that some of the attributes (like eventdesc) are only really relevant for the template display —?the descriptions are in the array regardless. So you may need to experiment a bit to see what data you’re getting.

    Thread Starter KlausFriese

    (@klausfriese)

    Amazing. Thanks a lot, that’s great. Works perfect, I added an JavaScript countdown and now I have a “next event xxx in 4 days 8 hours 15 minutes 46 seconds” text counting down to zero.

    My code is not yet finished, I will publish it here when it’s final.

Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘call Filter ICS Data before calender is displayed?’ is closed to new replies.