• Resolved netschmiede24

    (@netschmiede24)


    Hi,

    I have a pod with a datefield. Now I do want to still show the pod item, after the date is over – but I do want to add some extra content in the output, if the date was before today.

    So is there a possibility to write a template statement like this:

    [if date_field < today] THE DATE IS IN THE PAST.
    [else] THE DATE IS IN THE FUTURE.[/if]

    Thanks for your help!
    Astrid

Viewing 7 replies - 1 through 7 (of 7 total)
  • Plugin Support pd

    (@pdclark)

    This can be made available in a template with a shortcode defined in PHP.

    For example, adding the plugin below to wp-content/plugins/shortcode-past-future/shortcode-past-future.php and activating the plugin, or adding it with a Code Snippets plugin will:

    • Make [is_past]That was a great game![/is_past] display if date or date/time in field game_day is before now.
    • Make [is_future]We are looking forward to a great game![/is_future] display if date or date/time in field game_day is after now.
    • Make [is_past some_field_name]...[/is_past] will display if some_field_name contains a date or date/time in the past. Same for is_future.

    Technical details:

    • The line define( 'DEFAULT_DATE_FIELD_FOR_COMPARISONS', 'game_day' ); sets game_day to be the default field used if none is specified.
    • If a Date field is used, time will behave like it is set to midnight.
    • Unless the PHP default timezone is set, time calculations will likely be in the UTC timezone.
    • If a post_date or post_date_gmt field is required, modify the line $field_value = (string) get_post_meta( get_the_ID(), (string) $field_name, true ); to use get_post()->post_date_gmt or pods()->field('post_date_gmt') instead.
    • Due to the theory of relativity, Time/Space measurements are relative to a reference point and velocity. Therefore time is calculated here with strtotime(), where time is defined as number of seconds relative to the “beginning of time” for the Unix operating system: January 1, 1970 at midnight UTC. Other operating systems might use other reference points.
    • Velocity is considered negligible because even though it is estimated that the Earth is spinning at 1,670 km/h at the equator, orbiting the Sun at 107,200 km/h, traveling with the solar system around the Milky Way at 828,000 km/h, and moving through the wider universe at around 2.1 million km/h, we are all in the same boat, so we just call all that stuff “here and now”.
    <?php
    /**
    * Plugin Name: Shortcodes - Past/Future
    * Description: Display content if <code>name_of_field</code> in <code>[is_past name_of_field]</code> is in the past or <code>[is_future name_of_field]</code> is in the future. E.g., for a field named <code>game_day</code>, <code>[is_past game_day]Commentary[/is_past]</code> will display <code>Commentary</code> if the date/time in field <code>game_day</code> is before now.
    */

    // Default field to use for [is_past]...[/is_past] or [is_future]...[/is_future].
    define( 'DEFAULT_DATE_FIELD_FOR_COMPARISONS', 'game_day' );

    /**
    * [is_past name_of_field]...content...[/is_past]
    * or [is_past]...content...[/is_past]
    */
    add_shortcode(
    'is_past',
    function( $atts, $content, $tag ) {
    $timestamp = date_field_to_timestamp( $atts );
    if (
    ! empty( $timestamp ) // Timestamp is not empty, false, or zero.
    && $timestamp < time() // Timestamp is in the past.
    ) {
    return $content;
    }
    return '';
    }
    );
    /**
    * [is_future name_of_field]...content...[/is_future]
    * or [is_future]...content...[/is_future]
    */
    add_shortcode(
    'is_future',
    function( $atts, $content, $tag ) {
    $timestamp = date_field_to_timestamp( $atts );
    if (
    ! empty( $timestamp ) // Timestamp is not empty, false, or zero.
    && $timestamp > time() // Timestamp is in the future.
    ) {
    return $content;
    }
    return '';
    }
    );
    /**
    * A date field is a string (text characters).
    * A timestamp is an integer representing seconds since Jan 1 1970 UTC.
    */
    function date_field_to_timestamp( $atts ) {
    $field_name = (
    array_key_exists( 0, $atts )
    && ! empty( $atts[0] )
    ) ? $atts[0] : DEFAULT_DATE_FIELD_FOR_COMPARISONS;

    $field_value = (string) get_post_meta( get_the_ID(), (string) $field_name, true );

    if ( empty( $field_value ) ) {
    return false;
    }

    return (int) strtotime( $field_value );
    }
    Thread Starter netschmiede24

    (@netschmiede24)

    Hi,

    I added your code in Code Snippets (content) and activated it. However, adding this to my template:

    [is_past my_date_field] …content… [/is_past]

    is just displaying this in the front end:

    [is_past my_date_field] …content… [/is_past]

    If I am setting Code Snippets to function (PHP), it is not displaying anything at all.

    Just to make sure, I checked all the relevant settings to make shortcodes being displayed in templates. And I checked with a different shortcode, which displays as expected.

    And I also tried the plugin version instead. Same issue: it does not display anything at all.

    What am I missing?

    Thanks,
    Astrid

    Plugin Support pd

    (@pdclark)

    The two cases where nothing displayed is an indication the shortcode ran, but that the date stored in my_date_field was not considered to be in the past.

    • Is the date field literally named my_date_field?
    • Has a date been entered into that field for the post the template is displaying?
    • Are there any page builders or template systems being used which might cause the context of the shortcode to misinterpret what the current post is? (Try with a default theme, no page builder.)

    In testing, things worked within Pods Templates and auto-templates for both past and future. I noticed one bug where if the date was saved as blank, an empty field would be considered in the past… The fix to that was to change the last function date_field_to_timestamp to this:

    /**
    * A date field is a string (text characters).
    * A timestamp is an integer representing seconds since Jan 1 1970 UTC.
    */
    function date_field_to_timestamp( $atts ) {
    $field_name = (
    array_key_exists( 0, $atts )
    && ! empty( $atts[0] )
    ) ? $atts[0] : DEFAULT_DATE_FIELD_FOR_COMPARISONS;

    $field_value = (string) get_post_meta( get_the_ID(), (string) $field_name, true );

    if ( empty( $field_value ) ) {
    return false;
    }
    $timestamp = (int) strtotime( $field_value );
    if ( -62169984000 === $timestamp ) {
    return false;
    }

    return $timestamp;
    }

    The only other edge case I could identify would be if the Pods Template is being loaded from a shortcode (shortcodes within shortcodes). If that is the case, you might need to add this line to wp-config.php:

    define('PODS_SHORTCODE_ALLOW_SUB_SHORTCODES', true);
    Thread Starter netschmiede24

    (@netschmiede24)

    Hi again,

    the date is not named my_date_field, I just replaced that for better understanding. I have the correct field name of course in the shortcode.

    The datefield I use is a mandatory field, so it is not empty.

    I noticed one issue though – the Code snippet cannot be activated! I am not sure why this is? It looks like this: (button is in the middle and remains blank)

    Why is this? Can you help?

    Thread Starter netschmiede24

    (@netschmiede24)

    Ok – sorry for that – in the meantime, I had tried the plugin version, so the code was already there, that’s why I couldn’t activate the snippet.

    I am calling list via a Gutenberg widget (Pods elements list). Changing the template does not change the fact that nothing is being displayed where it should.

    Plugin Support pd

    (@pdclark)

    For the use case of a shortcode within a Pods Template within a looped block such as Pods Item List within a page builder such as Gutenberg:

    The block in this case, similar to elements or other page builders, does not currently have a way to inform the shortcode of the block’s context.

    Below is one solution, version 2 (full plugin), which requires the format [is_past my_date_field id="{@ID}"] …Content… [/is_past] for use in a Pods Template:

    <?php
    /**
    * Plugin Name: Shortcodes - Past/Future
    * Description: For a field named <code>my_date_field</code>, <code>[is_past my_date_field]Commentary[/is_past]</code> will display <code>Commentary</code> if the date/time in field <code>my_date_field</code> is before now. For use in Pods Templates, use <code>[is_past my_date_field id="{@ID}"]...Commentary...[/is_past]</code>.
    * Version: 2
    */

    /**
    * [is_past name_of_field]...content...[/is_past]
    */
    add_shortcode(
    'is_past',
    function( $atts, $content, $tag ) {
    $timestamp = date_field_to_timestamp( $atts );
    if (
    ! empty( $timestamp ) // Timestamp is not empty, false, or zero.
    && $timestamp < time() // Timestamp is in the past.
    ) {
    return $content;
    }
    return '';
    }
    );
    /**
    * [is_future name_of_field]...content...[/is_future]
    */
    add_shortcode(
    'is_future',
    function( $atts, $content, $tag ) {
    $timestamp = date_field_to_timestamp( $atts );
    if (
    ! empty( $timestamp ) // Timestamp is not empty, false, or zero.
    && $timestamp > time() // Timestamp is in the future.
    ) {
    return $content;
    }
    return '';
    }
    );
    /**
    * A date field is a string (text characters).
    * A timestamp is an integer representing seconds since Jan 1 1970 UTC.
    */
    function date_field_to_timestamp( $atts ) {
    $field_name = (
    array_key_exists( 0, $atts )
    && ! empty( $atts[0] )
    ) ? $atts[0] : DEFAULT_DATE_FIELD_FOR_COMPARISONS;

    // Pods Templates: Pass {@ID} to shortcode via id="{@ID}".
    $post_id = ! empty( $atts['id'] ) ? absint( $atts['id'] ) : get_the_ID();

    $field_value = (string) get_post_meta( $post_id, (string) $field_name, true );

    if ( empty( $field_value ) ) {
    return false;
    }
    $timestamp = (int) strtotime( $field_value );
    if ( -62169984000 === $timestamp ) {
    return false;
    }

    return $timestamp;
    }

    Alternatively, the plugin below can be added to make the id="{@ID}" addition unnecessary.

    The additional filter below changes the way Pods templates handle context — shortcodes within looped Pods Templates will have access to the global Post object the template is looping over.

    The filter below might align more closely with how some users may expect things should behave.

    It may also have consequences which could cause other unexpected behavior, as it transfers a partial shared context between systems which operate on different foundational assumptions.

    <?php
    /**
    * Plugin Name: Pods Templates - Global Post for Shortcodes
    * Description: Cause global <code>$post</code> functions to be available to shortcodes used in Pods Templates.
    * Version: 1
    */
    /**
    * May have unexpected consequences related to shortcode / magic tag processing order.
    * Does not change behavior of other query objects, e.g., taxonomies, users, etc.
    */
    add_filter(
    'pods_templates_do_template',
    function( $output, $code, $pod ) {
    if (
    ! is_object( $pod )
    || empty( $pod->pod_data )
    || 'post_type' !== pods_v( 'type', $pod->pod_data, '' )
    || empty( $pod->id() )
    ) {
    return $output;
    }
    ( new WP_Query( [ 'ID' => $pod->id() ] ) )->the_post();
    $output = do_shortcode( $output );
    wp_reset_postdata();
    return $output;
    },
    10,
    3
    );
    Thread Starter netschmiede24

    (@netschmiede24)

    Thank you, this works! (I used the one without the additional filter).

    All the best,
    Astrid

Viewing 7 replies - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.