Combine two Json files exported from wordpress Combine two Json files exported from wordpress wordpress wordpress

Combine two Json files exported from wordpress


How would I best go about merging the two?

Is it mandatory for you combine the two JSON files/data?

Because you could just require or load the JSON data from within your script (or even put them in the HTML) and then to get the meta value of a specific meta field/key, this function could do that:

// `single` has no effect if `meta_key` is empty.function getPostMeta( post_id, meta_key, single ) {    let id = String( post_id ),        pm = [];    postsMeta.map( m => {        let a = ( ! meta_key ) ||            ( meta_key === m.meta_key );        if ( a && id === m.post_id ) {            pm.push( m );        }    });    let meta = {},        mk = {};    pm.map( m => {        let k = m.meta_key, v;        if ( undefined === meta[ k ] ) {            meta[ k ] = m.meta_value;        } else {            v = meta[ k ];            if ( undefined === mk[ k ] ) {                meta[ k ] = [ v ];                mk[ k ] = 1;            }            meta[ k ].push( m.meta_value );            m[ k ]++;        }    });    pm = null;    mk = meta_key ? mk[ meta_key ] : null;    if ( mk ) {        return single ?            meta[ meta_key ][0] : // Returns a single meta value.            meta[ meta_key ];     // Returns all the meta values.    }    return meta_key ?        meta[ meta_key ] : // Returns the value of the `meta_key`.        meta;              // Or returns all the post's meta data.}

The data I used for testing: (take note of the postsMeta in the above/getPostMeta() function)

// Array of `post` objects.const posts = [{"ID":"19","post_author":"2","post_date":"2010-12-31 23:02:04","post_date_gmt":"2010-12-31 23:02:04","post_content":"Harry Potter was not available for the first sitting of the Halloween Picture. I hope everyone had a safe and fun Halloween. Tomorrow is picture retake day, please send back your previous prints if you want retakes. It is also hot lunch. See You tomorrow!","post_title":"Happy Halloween","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"open","post_password":"","post_name":"happy-halloween","to_ping":"","pinged":"","post_modified":"2011-01-03 05:26:11","post_modified_gmt":"2011-01-03 05:26:11","post_content_filtered":"","post_parent":"0","guid":"http:\/\/localhost\/mrskitson.ca_wordpress\/?p=19","menu_order":"0","post_type":"post","post_mime_type":"","comment_count":"1"}];// Array of `meta` objects.const postsMeta = [{"meta_id":"27","post_id":"19","meta_key":"large_preview","meta_value":"http:\/\/www.mrskitson.ca\/wp-content\/uploads\/2010\/12\/halloween.jpg"},{"meta_id":"28","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/facebook.com"},{"meta_id":"29","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/twitter.com"},{"meta_id":"30","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/linkedin.com"}];

Examples: (see this Fiddle for demo)

// In these examples, we are retrieving the meta value for the post #19 (i.e. ID is 19).// Retrieve a single value.// Returns mixed; string, number, etc.let url = getPostMeta( 19, 'large_preview', true );console.log( url );// Retrieve all meta values.// Always returns an array of values.let ms = getPostMeta( 19, 'many_values' );console.log( ms, ms[0] );// Retrieve all meta data.// Always returns an object with meta_key => meta_value pairs. I.e. { key => value, ... }let ma = getPostMeta( 19 );console.log( ma, ma.large_preview, ma.many_values[0] );

But if you really must combine the JSON data, you can do: (again, see demo on the same Fiddle)

// Here we modify the original `posts` object.posts.map( p => {    // Add all the post's meta data.    p.meta = getPostMeta( p.ID );    // Delete items you don't want..    delete p.post_parent;    delete p.menu_order;    // delete ...;});console.log( JSON.stringify( posts[0].meta ) ); // posts[0].meta = objectconsole.log( posts[0].post_parent, posts[0].menu_order ); // both are undefined

And then if you want to copy-paste the new/merged JSON data:

JSON.stringify( posts );

But if you actually just want to do something with the post's meta, you can loop through the posts object and do the thing; e.g.:

// Here the original `posts` object is not modified, and that we don't// (though you can) repeatedly call `getPostMeta()` for the same post.posts.map( p => {    // Get all the post's meta data.    let meta = getPostMeta( p.ID );    // Do something with `meta`.    console.log( meta.large_preview );});console.log( JSON.stringify( posts[0].meta ) ); // posts[0].meta = undefinedconsole.log( posts[0].post_parent, posts[0].menu_order ); // both still defined// posts[0].meta wouldn't be undefined if of course posts[0] had a `meta` item,// which was set in/via WordPress...


If you can do this in js, there's a pretty easy approach using Array#map. If you simplify your question, you're really asking how to add this meta data under each entry in posts, and get only the fields you want.

I'm assuming the posts.json is actually an array (e.g. [{"ID":"19"....).

// Load these server-side, fetch them remotely, copy-paste, etc.// I'll require them here for simplicityconst posts = require('./posts.json');const postsMeta = require('./postsMeta.json');// Build a Map so we can quickly look up the metas by post_id// Extract what we need by destructuring the argsconst metaByPost = postsMeta.reduce((a, {  post_id: id,  meta_value: value,}) => a.set(id, {  value,  /* anything else you want in here */,}), new Map());const mergedPosts = posts.map(post => ({  // Spread in the post  ...post,  // Spread in the meta content  ...metaByPost.get(post.ID),  // Undefine the props we don't want  post_parent: undefined,}));

I don't love manually setting stuff to undefined -- I think it's nicer to explicitly say what props you're going to include, instead of loading everything and undefining certain props.


Try this snippet directly in the Chrome DevTools console:

(function(  postsUrl='https://cdn.glitch.com/61300ea6-6cc4-4cb6-a62f-31adc62ea5cc%2Fposts.json?1525386749382',  metaUrl='https://cdn.glitch.com/61300ea6-6cc4-4cb6-a62f-31adc62ea5cc%2Fpostmeta.json?1525386742630') {  Promise.all([    fetch(postsUrl).then(r => r.json()),    fetch(metaUrl).then(r => r.json()),  ]).then(([postsResponse, metaResponse]) => {    // Inspected the actual JSON response to come up with the data structure    const posts = postsResponse[2].data;    const meta = metaResponse[2].data;    const metaByPostId = meta.reduce((accum, el) => {      accum[el.post_id] = el;      return accum;    }, {});    const transformedPosts = posts.map(post => {      const merged = {        ...post,        ...(metaByPostId[post.ID] || {}),      };      delete merged.post_parent;      // delete any other fields not wanted in the result      return merged;    });    console.log(transformedPosts);  });})();
  • replace URLs accordingly, I used the ones from Glitch example here
  • as commented, actual data is buried in response[2].data. Use Network tab / Parsed view to see structure
  • replace console.log with copy, if you want the result copied to clipboard, instead of logged to console