Site logo

[Resolved] loading an element content template in a custom location

Home Forums Support [Resolved] loading an element content template in a custom location

Home Forums Support loading an element content template in a custom location

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #2445401
    langlers

    I am working on a custom layout via a template filter in a plugin that loads and displays a single post via ajax after making certain form selections.

    In the template’s filter hook, I have the post_id. Is it possible to create a content template in elements (or whichever element type you suggest) that can be used within this filter hook?

    • I have tried creating a hook within my custom filter template which isn’t working.
    • I’ve also tried a portable hook and using a shortcode within my filter template which also isn’t working.
    • I also tried using the generate_element_display hook to enable it for my filter template–which also didn’t work.

    Elements with dynamic content are such a convenient way to build partial templates, that I would love to use them in this case, but I’m starting to think it’s not possible.

    I can provide examples of what I have tried out and access to the dev site, but before going there, I thought I’d just pose the general question:

    Can an element be used to change the layout of a single post displayed within another plugin’s filter hook?

    Thanks!

    #2445476
    langlers

    Here’s a generalized example of what I’m aiming to do:

    
    function show_post_with_element_content_template($item_html, $post_id) { 
        // Use an element content template with dynamic content (or block element, for example)        
        $element_id = 1234;
    	
        ob_start();
        $post = get_post($post_id); // specific post
        $the_content = apply_filters('the_content', $post->post_content);
        // --> Use $element_id as the content layout for the post...
        if ( !empty($the_content) ) {
          echo $the_content;
        }	
            
        $item_html = ob_get_clean();
    
        return $item_html; 
    }
    add_filter('my_plugins_item_html_template', 'show_post_with_element_content_template', 10, 2);
    
    #2446358
    David
    Staff
    Customer Support

    Hi there,

    elements are a custom post type ( gp_elements ), so where you have:

    $post = get_post($post_id);

    you should be able to simply do:

    $post = get_post($element_id);

    #2446841
    langlers

    Thank you for the suggestion.

    This definitely gets closer, but since I want to use the element with dynamic content as a template for another post, can i load an element in this fashion and also tell it which post to use as its source for the dynamic content?

    Load post_id using element_id as the template.

    #2446966
    David
    Staff
    Customer Support

    Ok, so you would need to make your own query for the post_id, and then output the element post content inside eg.

    
    // get the element
    global $post;
    $element_id = 451; // ID of the element
    $element = get_post($element_id);
    
    // get the post
    $args = array(
        'p'         => 28, // ID of a page, post, or custom type
        'post_type' => 'any'
    );
    // query for the ID
    $my_posts = new WP_Query($args);
    if ( $my_posts->have_posts() ) {
        while ($my_posts->have_posts()) : $my_posts->the_post();
            echo apply_filters('the_content',$element->post_content);
        endwhile;
        wp_reset_postdata();
    }
    #2447017
    langlers

    Thank you! This is now display the element, but I’m still seeing two issues:

    • This still shows the content layout element with placeholders like “TITLE” instead of replacing the dynamic content.
    • The CSS for the element isn’t being loaded.

    Here is an example of how I am using this:

    
    function my_demo_result_template($template, $demo_id, $posts) { 
         // The demo result I want to modify 
        if ($demo_id == 123) {
    	
    		// get the element
    		global $post;
    		$element_id = 456; // ID of the element
    		$element = get_post($element_id);
    
    		// get the posts to show in the demo result
    		$args = array(
    			'post_type' => 'any',
    			'post_status' => 'publish',
    			'post__in' => $posts,
    		);
    		// query for the ID
    		$my_posts = new WP_Query($args);
    		
    		ob_start();
    		if ( $my_posts->have_posts() ) {
    			while ( $my_posts->have_posts() ) : $my_posts->the_post();
    				echo apply_filters('the_content',$element->post_content);
    			endwhile;
    			wp_reset_postdata();
    		}
    		$template = ob_get_clean();
    		
        } 
        return $template; 
    }
    add_filter('demo/result/template', 'my_demo_result_template', 10, 3);
    

    Again, thank you so much for your help with this.

    #2447051
    David
    Staff
    Customer Support

    You need to pass the ID to the query args:

    
    $args = array(
    	'p' => $demo_id,
    	'post_type' => 'any',
    	'post_status' => 'publish',
    	'post__in' => $posts,
    );
    #2447103
    langlers

    To clarify, $demo_id is the page where I am calling the filter in order to display the content of the posts in $posts, which I hope to template using the element content layout of $element_id.

    If I add 'p' => $demo_id to the query args, wouldn’t that just tell the query to load the post $demo_id instead of the $posts in 'post__in' => $posts ?

    I can always recreate the element markup and css by hand, which will do the trick, but I was hoping to find a general solution here that I could reuse in other projects where I want to customize the output of a third-party plugin via its filter hooks but using the awesomeness of GP Elements.

    Use a filter to modify a template -> load the content of one or more posts -> use an element with dynamic content as the template for those posts.

    #2447120
    langlers

    Keeping everything else as-is in the previous code example, here is what I am seeing:

    The following loop correctly displays the IDs and titles of the posts in $posts within the filter on the page $demo_id

    
    if ( $my_posts->have_posts() ) {
    			while ( $my_posts->have_posts() ) : $my_posts->the_post();
    				echo "<p>" . get_the_id() . " " . get_the_title() . "</p>";
    			endwhile;
    		}
    

    However, if I replace the echo line showing the ID and title with a call to output the element in element_id, it loads and displays the element but without CSS and without replacing the dynamic content.

    
    if ( $my_posts->have_posts() ) {
    			while ( $my_posts->have_posts() ) : $my_posts->the_post();
    				echo apply_filters('the_content',$element->post_content);
    			endwhile;
    		}
    
    #2447834
    David
    Staff
    Customer Support

    If $demo_id == 123 is the post you want to output the element on.
    What is in the $posts variable ? Is this an array of Post IDs ?

    #2449397
    langlers

    Yes, $posts is just an array of post IDs.

    Apologies! I realize I started the thread asking about displaying one post and then switched the example code to loading multiple posts. After I read your example in #2446966 that started a new WP_Query, I just switched from a single 'p' => $post_id to multiple post__in => $post_ids.

    We could change the example to a plugin that, based on certain criteria, shows a few posts via a shortcode, the template of which can be overridden with a filter that passes the $template_html and the relevant $post_ids.

    Via this plugin’s filter, can I replace its $template_html with the GP content layout element, $element_id, that will dynamically show the content from $post_ids (let’s say that my layout element just shows a thumbnail and title)?

    • Is there a filter or other technique I can use to tell the $element_id to use each $post_id as the source for its dynamic content?
    • And is there a filter or other technique I can use to ensure that the css for $element_id is also loaded with the element?

    The above two things are where I have hit roadblocks in each solution I have attempted.

    #2450545
    David
    Staff
    Customer Support

    Ok, sorry for all the dumb questions lol, but i am unsure of a good way to filter in the template.
    For these kinds of thing i generally add an action hook inside my loop, and then hook in the block element.

    Is that not a possible option ?

    If not how and what is the function of the plugin ?

    #2451848
    langlers

    So digging deeper, it turns out the plugin is loading its content via wp_ajax. I didn’t realize this at first. I guess this would explain why the GP element isn’t redering correctly.

    In this case, I’ve opted to just copy out the element layout’s markup and css from a temporary page, and build a custom template from that which is now working in the plugins template filter.

    Before we close the ticket, out of curiosity, is there a way of using elements like this in content loaded via ajax? If not, it would be cool to have a function that would load a GP element in a sort of standalone manner with the option, for example, to include its css inline.

    Thanks for your help with this.

    #2454294
    David
    Staff
    Customer Support

    Try adding an action hook inside the plugins loop template.
    And then use a Block element – Hook type. Build your dynamic template there and try hooking that into your new hook.
    That way when the block element callback is made it should load the styles for it.

    #2468508
    langlers

    Thanks for all your help and suggestions.

Viewing 15 posts - 1 through 15 (of 16 total)
  • You must be logged in to reply to this topic.