1

I am using DataTables on this page.

It works great, except I've had trouble getting child rows to work.

I believe what I need to do is to convert the WP_Query results with associated custom fields into a JavaScript array.

It is easy enough to get the results of WP_Query in this manner, but when you add custom fields into the mix, I'm stuck.

Any ideas on how this can be accomplished? You can see the source code for the page here.

  • It's not quite clear what you need to achieve. What is your desired output? Which exact step of the process do you have trouble with? – Rarst Sep 15 '16 at 17:15
  • My desired output is an array that includes the custom fields data associated with each post and not just the standard post. I then need this to be converted to a JavaScript array so that DataTable can parse it. Hope that clarifies? – davemackey Sep 15 '16 at 17:16
  • This sounds more like generic PHP question. Do you know how to retrieve custom field data? Do you know how to manipulate it with PHP and output? What is the point where you don't know how to do next step? – Rarst Sep 15 '16 at 17:18
  • I don't know how to write a WP_Query that returns the custom field data. – davemackey Sep 15 '16 at 17:22
1

how to write a WP_Query that returns the custom field data

This is not typically necessary. You can simply access meta data for each post in query individually (as you do already). You can also iterate through query more than once in a page (it rewinds to start automatically, that's what while( have_posts() ) part does).

If you are concerned performance aspect — meta data access is heavily cached in memory (or object cache). Retrieving meta data multiple times in page load will not cause duplicate queries, it will only be fetched once and reused.

  • This works fine for PHP, but how do I make these returns into a JavaScript array? e.g., I can do: var data = json_encode($query -> posts()) But how do I get the custom fields to be included – davemackey Sep 15 '16 at 17:31
  • echo json_encode( $stuff ) ? :) – Rarst Sep 15 '16 at 17:31
  • json_encode()? -- beat me to it :) – FaCE Sep 15 '16 at 17:32
  • Yes, but then I have two different sets of json, one with the main post content and another with custom fields content - but I want to return both of these together. – davemackey Sep 15 '16 at 17:33
  • Combine them into a single data set with PHP first. Create array, add data to array as necessary, output resulting array as you need. – Rarst Sep 15 '16 at 17:34
1

Here's an over-simplified example of what you might want to do: Use the JsonSerializable:

class \JsonQuery extends \WP_Query implements \JsonSerializable
{
    public function jsonSerialize()
    {
        return array_map( function( \WP_Post $post ) {
            return array_merge( 
                $post->to_array(),
                get_post_custom( $post->ID )
            );
        }, $this->get_posts() )
    }
}

It's as easy as that (…above). Now just query whatever you need and

// Enqueue script here!
$query = new \JsonQuery( [
    /* arguments you use in normal \WP_Query */
] );
wp_localize_script( 'script-handle', 'globalJsVarName', json_encode( $query ) );

Then you have your JSON-encoded query alongside all post custom data.

Note:

  1. Above code is not tested (actually I had two phone calls in between, so it might be slightly off here and there)
  2. Make sure to enqueue the script upfront so you can localize data for it.
  3. Make sure that you either put the JS in the footer (last arg when registering) or query early enough – not sure that works.

Edit

You might want to write a Decorator for \WP_Query instead of extending it. The internet will tell you about the Pros/Cons so no need to repeat it here.

0

Okay, I THINK I understand what you're asking for, feel free to tell me I'm in left field.

First off, you'll want to take a look at this: https://aarontgrogg.com/blog/2015/12/16/getting-to-know-and-adding-json-ld-to-a-wordpress-site/

Now I was using this specifically to get Schema Data, but I believe you could deliver other types of payloads, such as javascript.

The main question is then how to get the custom field data into your payload, which I think is what you're really asking?

Anyway, using the method described in that link to create my json, I've got this in my head -

<?php include('json-ld.php');?>
<script type="application/ld+json"><?php echo json_encode($payload); ?></script>

Then in my json-ld.php file I have this:

<?php 
// JSON - LD for Reaction 

// Global Call

function get_post_data() {
    global $post;
    return $post;
}


$post_data = get_post_data();
$payload["@context"] = "http://schema.org/";

//blog posts

if (is_singular('post')) {

    //variables for the post

    $post_url = get_permalink();
    $post_thumb = wp_get_attachment_url(get_post_thumbnail_id($post->ID));
    $excerpt= get_the_excerpt($post->ID); //  grab the post excerpt.
    $author_select = get_field('author', $post->ID);
    $moddatetime = new DateTime($post_data->post_date); 


    // getting the team member


    if ($author_select == 'reaction') {

        $postauthor = 'Reaction';

    } 

    else if ($author_select == 'guest') { 

         $postauthor = get_field('guest_writer_name', $post->ID);

    } else {

        $author = get_field('team_member', $post->ID);
            foreach($author as $member) {               
            $postauthor = $member->post_title;
        }

    }

    // getting the tags

    $posttags = get_the_tags();
    if ($posttags) {
      foreach($posttags as $tag) {
       $value .= $tag->name . ', '; 
      }
    }
    $value = rtrim($value,', ');


    //payload

    $payload["@type"] = "blogPost";
    $payload["url"] = $post_url;
    $payload["creator"] = array(
        "@type" => "Person", 
        "name" => $postauthor, // outputs my post author as per the calls above
        ); 

    $payload["headline"] = $post_data->post_title; // works
    $payload["datePublished"] = $moddatetime->format(DateTime::ISO8601);  // works
    $payload["image"] = $post_thumb;
    $payload["description"] = $excerpt; // works
    $payload["about"] = $value; // works

}


// home page

if (is_front_page()) {

    $logourl = get_site_url();


    $payload["@type"] = "Organization";
    $payload["name"] = "Reaction Marketing";
    $payload["logo"] = $logourl . '/reaction-logo.png';
    $payload["url"] = get_site_url();
    $payload["sameAs"] = array("http://twitter.com/reaction", "https://www.facebook.com/ReactionMarketing", "http://www.linkedin.com/company/reaction-marketing");
    $payload["contactPoint"] = array(array("@type" => "ContactPoint", "telephone" => "+1 403 346 6580", "email" => "info@reaction.ca", "contactType" => "sales"));
}

?>

My end result is a schema appropriate to the page and post. Home page output example here:

<script type='application/ld+json'>{"@context":"http:\/\/schema.org","@type":"WebSite","url":"http:\/\/reaction.ca\/","name":"Reaction","alternateName":"Reaction","potentialAction":{"@type":"SearchAction","target":"http:\/\/reaction.ca\/?s={search_term_string}","query-input":"required name=search_term_string"}}</script>
<script type='application/ld+json'>{"@context":"http:\/\/schema.org","@type":"Organization","url":"http:\/\/reaction.ca\/","sameAs":["https:\/\/www.facebook.com\/ReactionMarketing","https:\/\/www.instagram.com\/reaction","https:\/\/www.linkedin.com\/company\/reaction-marketing","https:\/\/twitter.com\/reaction"],"name":"Reaction Marketing","logo":"http:\/\/reaction.ca\/uploads\/REACTION-RGB.jpg"}</script>

Now, obviously this is specific to schema, but you can see in there that I've called data specific to various custom fields (using ACF). You can see specifically how my variables are being called in blog posts there.

Does this seem to fit what you're asking?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.