Working with Wordpress

A slight detour here just wanted to talk about WordPress development —not actually cutting edge— but since I’ve been working on a few WordPress projects lately I thought I’d share some of my tips, plus remember if you’re good at WordPress you could make a decent amount of ¥¥¥.

Prerequisites
This is my enviroment.

  • Mac OSX v10.11.3 (El Capitan)
  • Homebrew 0.9.5
  • Docker 1.9.0
  • Docker Kitematic 0.9.3

Choosing the right Template
There are myriads of templates out there with varying difficulties.

Got a bit of learning curves
https://github.com/Obox/layerswp this one is quite unique since it extends the WordPress Customizer.
https://github.com/somerandomdude/Frank
https://github.com/roots/bedrock
https://github.com/roots/sage
https://github.com/Automattic/_s
https://github.com/mattbanks/WordPress-Starter-Theme

Just bare template
https://github.com/thethemefoundry/make

Most of them are already using the Gulp/Grunt combination so if you’re unfamiliar with it then get cracking.

Using Docker for Development Environment
The zeitgeist! Docker can be seen in every corner at the moment and you can integrate it with any type of application and it’s easy, I had the Tensorflow set up within minutes, although there are a few quirks in using Docker and Kitematic so I recommend you to delve more since you’d be able to debug your environment lest something happens.

The first thing you have to do is download Docker Toolbox and Kitematic, you can go to their website and download it like when Windows 95 was still around or use brew cask.

$ brew cask install dockertoolbox
$ brew cask install kitematic

And afterward, just start Kinematic up! you’ll immediately be presented with this window.

Lovely UI isn’t, this is what sold me the first time!

Now that you have everything up and running, the next thing you need to do is to create the docker-compose.yml, start by opening up the CLI (at the bottom left) and type in the code below.

$ mkdir wordpress 
$ cd wordpress 
$ vi docker-compose.yml

And paste this code, I’ve added a very generic comment, again Docker is a broad topic so try to read their website.

And then build the container;

$ docker-compose -d

Once everything has been built, go to the Kitematic window and you’ll see the WordPress container listed, click the setting tab and then Ports, where you’ll find the IP address, click that and it’ll automatically open the WordPress site.

Once you finished you can click the stop button on the Kitematic window or start to initiate it.

Other Environments
There are alternatives besides Docker that you can choose the easiest one would be MAMP (A slight warning there’re a few system conflicts on El Capitan), another one would be Trellis which is based on Vagrant or if you’re adventurous you could install Centos and, of course, El Capitan comes with its own apache server.

Ajax Page Transition
The fun part in developing WordPress —well, relatively speaking— would be avoiding all the plugins peril, since a copious amount of it will bog down your site.

There are a lot of websites that talks about building your own plugin, but something that compelled me was Ajax Page Transition since you could create an uninterrupted experience plus is super-cool. (Some of you would probably snigger in disgust right now)

Before I start I need to remind you that the proper way to handle AJAX in WordPress is to use; register, enqueue and localize the JavaScript files using wp_enqueue_scripts instead of wp_print_scripts.

The system can be achieved with a simple Ajax and a hint of History API, have a look at the diagram below;

diagram

It’s pretty simple isn’t! Onwards with the code.

First, you need to structure the template accordingly so it’ll be easier to extract and/or overwrite the content later, like so;

<body>

     <!-- The content div would be used as a container -->
     <div id="content">
          <h1>About Us</h1>
          <p>Lorem ipsum..</p>
     </div>

</body>

Second, to change the URL path without refreshing the browser, utilize the history data.


// when the back button is pressed, each recorded history will be removed
// this listener will listen to that event
window.onpopstate = function(event) {
   // Update whatever you have on the page
    updatePage();
}

// This is just to illustrate the function
function callPage(url, pageData) {

  // If you're using old browser don't forget to add a fallback
  history.pushState(pageData, pageData.title,  url);

}

// Trigger this method through button click
callPage("/about/", { item: { title: "About us" } });

There’s not much to it, you can read it more here if you want and if you need a fallback you can use history.js.

Afterwards, call the page through Ajax.

function connectPage(url, data ) {

    $.ajax(
      // type: 'GET', // optional
      url: url, // pass the page url
      data: data // add this to pass data between content
      cache: false, //Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters
      // dataType: 'html',  //optional
      success: function(data) {

        if(data.length) {

          // Handle Error
          onError("Data empty");
        }

        // Handle success
        onSuccess(data);

      },
      error: function(errorThrown) {

        // Handle Error
        onError(errorThrown);

      }
    )

}

connectPage("/about/", {});

As you can see you probably could merge those two functions together.

Once the data is extracted, the next step would be isolating and attaching the HTML content.

function onSuccess(data) {

    data = data.split('id="content"')[1]; // the ID name can be anything you want.
    data = data.substring(data.indexOf('>') + 1);

    var depth   = 1,
    output      = '';

    while(depth > 0) {
      var temp = data.split('</div>')[0];
      var i = 0;
      var pos = temp.indexOf('<div');

      while(pos != -1) {
        i++;
        pos = temp.indexOf('<div', pos + 1);
      } 


      depth   = depth + i - 1;
      output  = output + data.split('</div>')[0] + '</div>';
      data    = data.substring(data.indexOf('</div>') + 6);
     
    }

    // attach the HTML output
    document.getElementById("content").innerHTML = output;

    // Update Google Analytics
    ga('set', { page: window.location.pathname })
    ga('send', 'pageview')

    // Update page
    updatePage();

}

Retreiving Post with Nonce

By using nonce (number used once) your site will be protected against cross-site request forgery.

For instance, if we wanted to retrieve a certain post, then we could do something like this.

Modify the Ajax call we had earlier.

connectPage("/about/", {
  action: 'get_post_ajax',
  postID: id, // The Wordrpess post ID
  security: <?php wp_create_nonce  ('blahblah'); ?>
});

Then on functions.php check for the value;

  function get_posts_ajax() {

      if ( isset($_REQUEST) ) {

          check_ajax_referer('blahblah', 'security' );

          $post_id    = sanitize_text_field($_REQUEST['postID']);
          $post_info  = get_post(intval($post_id));

          $cat        = get_the_category(intval($post_id));
          $cur_cat_ID = $cat[0]->cat_ID;
          $args       = array(
            'category'  => $cur_cat_ID,
            'orderby'   => 'post_date',
            'order'     => 'DESC'
          );

          $posts  = get_posts( $args );

          wp_send_json(array(
            'ID'                    => $post_info->ID,
            'post_author'           => $post_info->post_author,
            'post_date'             => $post_info->post_date,
            'post_date_gmt'         => $post_info->post_date_gmt,
            'post_content'          => $post_info->post_content,
            'post_title'            => strtoupper($post_info->post_title),
            'post_excerpt'          => $post_info->post_excerpt,
            'post_status'           => $post_info->post_status,
            'comment_status'        => $post_info->comment_status,
            'ping_status'           => $post_info->ping_status,
            'post_password'         => $post_info->post_password,
            'post_name'             => $post_info->post_name,
            'to_ping'               => $post_info->to_ping,
            'pinged'                => $post_info->pinged,
            'post_modified'         => $post_info->post_modified,
            'post_modified_gmt'     => $post_info->post_modified_gmt,
            'post_content_filtered' => $post_info->post_content_filtered,
            'post_parent'           => $post_info->post_parent,
            'guid'                  => $post_info->guid,
            'menu_order'            => $post_info->menu_order,
            'post_type'             => $post_info->post_type,
            'post_mime_type'        => $post_info->post_mime_type,
            'comment_count'         => $post_info->comment_count,
            'filter'                => $post_info->filter
            )
          );

      }

      wp_die();
  }

Conclusion
When working with WordPress the first thing that you always need to consider is the security aspect, its ubiquitousness attracts hacks, always follow the best practice (not guaranteed), learn about the basic security hacks, implement re-captcha, update the WordPress constantly, etc.

Another note also WordPress is notorious for its sluggishness but then again there is a trade-off that can be had, huge communities, endless plugins (but don’t use it too much), is great for obnoxious client 🙂 , but if speed is what you after then I suggest you try Amplify or Ghost.

Leave a Reply

Your email address will not be published. Required fields are marked *