Displaying a WordPress post via a returned JSON id from a remote non-WP site

I have a Wordpress site that will be pushing remote calls to a non Wordpress application (one that is making predictive decisions). The system my WP site is talking to will then return a post id to me (for sake of argument here). I want to, in the simplest way possible, then load only that post id in the center content area.

I've tried many different plugins, but they either aren't well documented or don't handle decoding json that's returned into WP and parsing it.

I just need to understand how I can have a plugin that does a remote get, receives a response, parses it according to the Wordpress way (against the wp-query loop) and returns content. I have looked high and low for just an example and so far, I just feel flooded with too much info.

Does WPMU have a plugin or approach that would help me with this?

Also, here's how far I've gotten in coding a plugin solution:

function testing_Get_CURL (){
$url = 'http://myremotesitenotWP/event/94303?radius=30';

$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 0);
$result = curl_exec($ch);
curl_close($ch);

// Prepare the data:
$content = trim( wp_remote_retrieve_body( $result ) );
// Convert output to JSON
if (
strstr(
wp_remote_retrieve_header( $result, 'content-type' )
,'json'
) )
{
//this is where my post id comes back....not sure how to decode and see the results //and how to pluck the post out of it for loading into the middle content area
$content = json_decode( $content );
}
}

And here'sthe response if I run the CURL from the CLI:

{"0.0": {"event_id": "1179", "post_id": "1564"}}

Maybe my above code is close? But I need to know how to demo it for myself. How to load the returned content, see it change based on passing different zip codes or whatever and to see the posts hit the wp_query.

  • Tom Eagles

    Hi the Oedipa

    Have found a few resources for you with reference to this and am listing them here, will also ask our lead developer @Aaron for feedback on this.

    http://www.fldtrace.com/wordpress/display-latest-post-outside-of-wordpress-with-json-and-jquery
    https://github.com/dphiffer/wp-json-api/blob/master/singletons/query.php
    http://wordpress.org/plugins/json-api/other_notes/
    http://stackoverflow.com/questions/6635336/how-do-you-output-json-using-wp-query-in-wordpress
    http://stackoverflow.com/questions/9910596/manually-retrieve-wordpress-posts-with-category-tags-for-json

    Cheers

  • Imperative Ideas

    Why not have the WP loop write a JSON object directly? For example, in order to use a jQuery based timeline plugin on one of my themes, I had the loop output things in a non-standard way (includes a fallback to the original, which is cleared in jQuery before viewing):

    <!-- Initialize Timeline Script (full page) -->
    
    <?php
    
    $paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
    $args = array(
        'post_status' => 'publish',
        'post_type' => 'post',
        'order' => 'DESC',
        'orderby' => 'post_date',
        'posts_per_page' => '10',
        'offset' => '1',
        'paged' => $paged
    );
    
    global $frontpage_query;
    $frontpage_query = new WP_Query( $args ); ?>
    
    <script type="text/javascript">
        jQuery(document).ready(function($) {
            var timeline_data = [
    
                <?php if($frontpage_query->have_posts()) : while($frontpage_query->have_posts()) : $frontpage_query->the_post(); ?>
                <?php $authorname = get_the_author(); ?>
    
                <?php if( has_post_format('gallery')) { ?>
    
                    /* JSON Setup */
    
                <?php } elseif( has_post_format('image')) { ?>
    
                    /* JSON Setup */
    
                <?php } elseif( has_post_format('audio')) { ?>
    
                    /* JSON Setup */
    
                <?php } else { ?>
    
                    {
                        type:        'blog_post',
                        date:        '<?php the_date("Y-m-d"); ?>',
                        dateFormat:  'DD MMMM YYYY',
                        title:       '<?php echo get_the_title(); ?>',
                        width:       400,
                        content:     '<?php echo get_the_excerpt(); ?>',
                        image:       '<?php echo get_the_post_thumbnail($post->ID, 'timeline'); ?>',
                        fullsize:    '<?php echo get_the_post_thumbnail($post->ID, 'full'); ?>',
                        author:      '<?php echo get_the_author(); ?>',
                        authorlink:  '<?php echo get_author_posts_url( get_the_author_meta( 'ID' ) ); ?>',
                        readmore:    '<?php echo get_permalink(); ?>'
                    },
    
                <?php } ?>
    
                <?php endwhile; ?>
    
            ];
    
            var timeline = new Timeline(jQuery('#timeline'), timeline_data);
            if( screenwidth > 900 ) {
                timeline.setOptions({
                    animation:   true,
                    lightbox:    true,
                    showYear:    true   ,
                    allowDelete: false,
                    columnMode:  'dual',
                    order:       'desc'
                });
                timeline.display();
            } else {
                timeline.setOptions({
                    animation:   true,
                    lightbox:    true,
                    showYear:    true,
                    allowDelete: false,
                    columnMode:  'center',
                    order:       'desc'
                });
                timeline.display();
            }
    
        });
    </script>
    
    <?php else : ?>
    
        <p class="no-posts"><?php _e('Sorry, no posts matched your criteria', 'example'); ?></p>
    
    <?php endif; ?>
    
    <div id="timeline">
        <div id="timeline-html">
            <?php rewind_posts() ?>
            <?php if(have_posts()) : while(have_posts()) : the_post(); ?>
                <article itemscope="" itemtype="http://schema.org/Type" itemid="http://schema.org/BlogPosting" class="timeline_element blog_post animated" style="width: 400px;">
                    <link itemprop="subClassOf" href="http://schema.org/Article">
                    <h2><a href="<?php echo get_permalink(); ?>"><?php the_title(); ?></a></h2>
                    <h3>By <?php the_author(); ?> on <?php the_date(); ?> </h3>
                    <?php echo get_the_post_thumbnail($post->ID, 'timeline'); ?>
                    <?php the_excerpt(); ?>
                    <span class="vcard author" style="display:none;">
                                <span class="fn">Written by <a href="<?php echo get_the_author_link() ?>"><?php the_author(); ?></a></span> on <span class="updated"><?php the_modified_date(); ?></span>
                            </span>
                </article>
    
            <?php endwhile; ?>
            <?php else : ?>
    
                <p class="no-posts"><?php _e('Sorry, no posts matched your criteria', 'example'); ?></p>
    
            <?php endif; ?>
        </div>
    </div>

    If you have to push the data, you could trigger a listener script on publish, which might be a whole lot simpler than the current approach.

  • Oedipa

    Hmmm...not sure how I would implement something like the above Timeline code to my particular project. And granted, it's a peculiar project. We have Wordpress as a kind of "front door", if you will, to a powerful AI system on the backend. My Wordpress site and the AI system are going to talk to one another on every user visit via JSON. So when a user visits, Wordpress sends the AI system information gathered on the user and then the AI responds back with a location/post/event ID (used in events manager to define the location of certain events). So in order to simplify this whole approach, I think of the location ID as a post ID.

    Now, the code I included will hopefuly push a pretend request out (for purposes of testing) and then receive the location or event ID I have in my dummy json on the AI system right now.

    What I'm now wrestling with are two things: Where/how to implement the rudimentary code I have posted in my original question (the CURL code). A template in my theme? Or a plugin? Will this work in the long run for a push/response system like I described? I'm leaning towards putting this code in a template to at least see one round trip of these two systems talking to one another.

    With the above Timeline code, I'm guessing you're constructing the JSON object after the response is received and you're showing me how I could use the parsed elements to further define the output with wp_query? I'm at the most simple state right now, that I simply want to understand more about how to use the HTTP API (which I have only been reading about this week) to accomplish the push/response.

    So far, asking this question on Stackoverflow, Wordpress Answers and in various PHP list serves has netted zero responses. Either people don't understand what I'm trying to acheive or it's so painfully obvious, they can't understand why I don't just see it, or it's never been done before.

    I'll continue reading the links posted above too. So much information to absorb! Thanks for your responses!!!!

  • Aaron

    I'm not quite sure what you are trying to acheive. How will you trigger the post to your remote system? Is it part of a user initiated action like a page request? Then you would just tie into a hook for that action.

    Or do you want to implement a schedule? If so you will want to use the wp cron api.

    Or you could trigger it from your other system and access a callback url on your WP site.

    Once your plugin get's the post id, you can just call get_post() http://codex.wordpress.org/Function_Reference/get_post

  • Oedipa

    Yeah...I'm looking at implementing get_post now.

    What I'm trying to acheive, and I may have taken up too many words in my previous response, is to simply talk to this really weird AI system that ALSO holds post ids in its system. When I have a visitor, I send their IP address to this AI system, and the AI system then knows what post id to send back (based on their location). So I know that it's really weird to have a seperate system also containing post ids when it's not WP, but there you go. It's what I'm dealing with.

    When I get the JSON back, it looks like this: {"event_id": "1179", "post_id": "1564", "location_id": "19", "location_postcode": "94301"}

    Let's just call this AI system Skynet. So my application or plugin or addition to a template (not sure which yet) will push a curl get (is there a better way? wp_remote?) to this Skynet-like thing, Skynet responds with the above and I capture that response (again, does my code look like it's on the right track for doing that in my original post?) and then I json_decode, grab the key-->values and then submit the ids to something like get_post_by_id or whatever is out there. I figured a loop even sort of like:

    get_posts();
    
        $validPosts = array();
        $this_post = array();
        $id_post = array();
        $i = 0;
    
    //so once i pull the post id, it gets passed here into a variable that will act as the id
        $my_query = new WP_Query( 'p=7' );
    
        if($my_query->have_posts()) {
            while($i < $my_query->post_count) :
                $post = $my_query->posts;
    
                if(!in_array($post[$i]->ID, $id_post)){
                    $this_post['id'] = $post[$i]->ID;
                    $this_post['post_content'] = $post[$i]->post_content;
                    $this_post['post_title'] = $post[$i]->post_title;
                    $this_post['guid'] = $post[$i]->guid;
    
                    $id_pot[] = $post[$i]->ID;
                    array_push($validPosts, $this_post);
    
                }
    
                $post = '';
                $i++;
    
            endwhile;
    //figure out how to display the posts you put in the array onto a page now
        }

    But I'm trying to make sure that I'm:

    1) On the right tract with the CURL approach, or should I be doing something more elegant for the push and response?
    2) On the right track with the json_decode of the response and then parsing it to pull post data like the snippet I posted above.

    And yeah, I'm familiar with WP, but more from an OPs side. This is definitely taking my developer skills up a notch. I did read about the HTTP API and it almost seems like I should be using more WP "friendly" HTTP functions like wp_remote_get or something.... Essentially, this is the advice I'm seeking. :slight_smile:

    Does that make sense? I realize using Wordpress to communicate with Skynet is a weird project. I don't blame anyone for being confused about my goals here.

  • Oedipa

    Well looks like I'm close, but json_decode just plain does NOT want to work in WP. I've tried every example I could find out there, but I can't return anything from my json array...making it pretty difficult for me to get the post_id to submit into get_post:

    function my_Get_CURL (){
    $url        = 'http://nonWPserver/event/94303?radius=30';
    //  Initiate curl
        $ch = curl_init();
    // Disable SSL verification
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    // Will return the response, if false it print the response
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    //header
    $headers = array(
        'Content-type: application/json'
    );
    curl_setopt($curlHandle, CURLOPT_HTTPHEADER, $headers);
    // Set the url
        curl_setopt($ch, CURLOPT_URL,$url);
    // Execute
        $json_content=curl_exec($ch);
    
    $json = json_decode($json_content, true);
    //echo $json_content;
        return array(
             'distance' => $json_content->distance,
            'data' => $json_content->data
        );
    }
    
    add_filter('the_content', 'my_Get_CURL', 1,3);

    Doing an echo or var_dump on this code nets me:

    [{"distance": 0.0, "data": {"event_id": "1179", "post_id": "1564", "location_id": "19", "location_postcode": "94301"}}, {"distance": 2.162680661505968, "data": {"event_id": "1193", "post_id": "1578", "location_id": "19", "location_postcode": "94301"}}]

    What have I done wrong? I was just using json_decode (with and without the true flag). Why won't it decode? How can I access my array elements if this won't work?

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.