Zombie Posts/Pages Shortcode

Origin Story

This is an odd one but has a number of uses outside this weird scenario. In this case authors have access to Site B but want the content they write to show up on Site A on the appropriate pages/posts. Given this is a multisite I could tie the sites together and do the switch_to_blog so that posts updated on Site B update Site A. I could also periodically clone the whole site to the destination etc. This all felt fairly aggressive and lacking in flexibility. It seemed like it’d have the potential to go very wrong and would require a lot of thinking to prevent abuse while allowing for flexibility.

JSON API Route

I decided instead to create a little shortcode that would let you pick a site URL (any site), add a post type, the content ID and that would spit the content of that target out in your page/post. There are search, SEO concerns with this route but it’s a decent path for a quick solution.

function post_clone_wars_shortcode( $atts, $content = null ) {
    extract(shortcode_atts( array(
         'site' => '', //site id 
         'type' => '', //content type - page or post
         'id' => '', // id of the page or post
    ), $atts));         

    if($site){
        $site = ' data-site="'.$site.'"';
    } 
    if($type){
        $type = ' data-type="'.$type.'"';
    }
    if($id){
        $id = ' data-id="'.$id.'"';
    } 
    
    
    $html = '<div id="clone-wars" '.$site. ' ' . $type. ' ' . $id . '></div>';

    return  $html;
}
add_shortcode( 'clone-wars', 'post_clone_wars_shortcode' );

function cloneWarsGetContent(){
 
//see if we've got the shortcode div before running all this stuff
  try {
  let element = document.getElementById('clone-wars');
    return element;
  }
  catch(err) {
      console.log(err.message);
  }
}

  if (cloneWarsGetContent()){ 
  let element = document.getElementById('clone-wars');
  let site = element.dataset.site;
  let type = element.dataset.type;
  let contentId = element.dataset.id;
  let url = site + '/wp-json/wp/v2/' + type + '/' + contentId;
   
    console.log(url);//what's our final url?

    jQuery(document).ready(function() {
      var def = new jQuery.Deferred();
      jQuery.ajax({
        url: url,
        jsonp: "cb",
        dataType: 'json',
        success: function(data) {
            //console.log(data); //dumps the data to the console to check if the callback is made successfully.
              console.log(data)
              jQuery('#clone-wars').html(data.content.rendered);
          } //success
      }); //ajax  
    }); //ready
  }


As I write this, I now realize I could do this a lot better with a check of the API content and then setting this to update the content if the data differs. That is one of the advantages of writing posts about stuff. You think about it a bit more and come up with better ideas because you’re taking the time to try to communicate it to others. It also helps me remember that I did it at all which is good for my mental health1 and helps me find it again later.


1 I have done things. There is proof. I forget positive things too soon and dwell on the negative so this helps prevent that.