{"id":1583,"date":"2016-03-24T09:52:44","date_gmt":"2016-03-24T09:52:44","guid":{"rendered":"http:\/\/bebensiganteng.com\/?p=1583"},"modified":"2016-09-26T12:23:23","modified_gmt":"2016-09-26T12:23:23","slug":"working-with-wordpress","status":"publish","type":"post","link":"https:\/\/rahmat-hidayat.com\/?p=1583","title":{"rendered":"Working with WordPress"},"content":{"rendered":"<p>A slight detour here just wanted to talk about WordPress development \u2014not actually cutting edge\u2014 but since I&#8217;ve been working on a few <a href=\"http:\/\/www.hoyu.com.sg\/\" target=\"_blank\">WordPress<\/a> <a href=\"https:\/\/millian.sg\/\" target=\"_blank\">projects<\/a> lately I thought I&#8217;d share some of my tips, plus remember if you&#8217;re good at WordPress you could make a <a href=\"https:\/\/www.reddit.com\/r\/Wordpress\/comments\/47r02g\/im_a_freelance_wordpress_developer_who_completed\/\" target=\"_blank\">decent amount of \u00a5\u00a5\u00a5.<\/a><\/p>\n<p><img decoding=\"async\" src=\"http:\/\/i.imgur.com\/3EDDB13.gif\" style=\"width:100%; height: auto\" \/><\/p>\n<p><strong>Prerequisites<\/strong><br \/>\nThis is my enviroment.<\/p>\n<ul>\n<li>Mac OSX v10.11.3 (El Capitan)<\/li>\n<li>Homebrew 0.9.5<\/li>\n<li>Docker 1.9.0<\/li>\n<li>Docker Kitematic 0.9.3<\/li>\n<\/ul>\n<p><strong>Choosing the right Template<\/strong><br \/>\nThere are myriads of templates out there with varying difficulties. <\/p>\n<p><em>Got a bit of learning curves<\/em><br \/>\n<a href=\"https:\/\/github.com\/Obox\/layerswp\" target=\"_blank\">https:\/\/github.com\/Obox\/layerswp<\/a> this one is quite unique since it extends the WordPress Customizer.<br \/>\n<a href=\"https:\/\/github.com\/somerandomdude\/Frank\" target=\"_blank\">https:\/\/github.com\/somerandomdude\/Frank<\/a><br \/>\n<a href=\"https:\/\/github.com\/roots\/bedrock\" target=\"_blank\">https:\/\/github.com\/roots\/bedrock<\/a><br \/>\n<a href=\"https:\/\/github.com\/roots\/sage\" target=\"_blank\">https:\/\/github.com\/roots\/sage<\/a><br \/>\n<a href=\"https:\/\/github.com\/Automattic\/_s\" target=\"_blank\">https:\/\/github.com\/Automattic\/_s<\/a><br \/>\n<a href=\"https:\/\/github.com\/mattbanks\/WordPress-Starter-Theme\" target=\"_blank\">https:\/\/github.com\/mattbanks\/WordPress-Starter-Theme<\/a><\/p>\n<p><em>Just bare template<\/em><br \/>\n<a href=\"https:\/\/github.com\/thethemefoundry\/make\" target=\"_blank\">https:\/\/github.com\/thethemefoundry\/make<\/a><\/p>\n<p>Most of them are already using the Gulp\/Grunt combination so if you\u2019re unfamiliar with it then get cracking.<\/p>\n<p><strong>Using Docker for Development Environment<\/strong><br \/>\nThe zeitgeist! Docker can be seen in every corner at the moment and you can integrate it with any type of application and it&#8217;s easy, I had the <a href=\"https:\/\/www.tensorflow.org\/\" target=\"_blank\">Tensorflow<\/a> set up within minutes, although there are a few quirks in using Docker and Kitematic so I recommend you to <a href=\"https:\/\/www.docker.com\/\" target=\"_blank\">delve more<\/a> since you&#8217;d be able to debug your environment lest something happens.<\/p>\n<p>The first thing you have to do is download <a href=\"https:\/\/www.docker.com\/products\/docker-toolbox\" target=\"_blank\">Docker Toolbox<\/a> and <a href=\"https:\/\/kitematic.com\/\" target=\"_blank\">Kitematic<\/a>, you can go to their website and download it like when Windows 95 was still around or use brew cask.<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n$ brew cask install dockertoolbox\r\n$ brew cask install kitematic\r\n<\/pre>\n<p>And afterward, just start Kinematic up! you&#8217;ll immediately be presented with this window.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/i.imgur.com\/iAxsi07.jpg\" alt=\"\" \/><\/p>\n<p>Lovely UI isn&#8217;t, this is what sold me the first time!<\/p>\n<p>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.<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n$ mkdir wordpress \r\n$ cd wordpress \r\n$ vi docker-compose.yml\r\n<\/pre>\n<p>And paste this code, I&#8217;ve added a very generic comment, again Docker is a broad topic so try to read their website.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/bebensiganteng\/11f3f948e11ab7575434.js\"><\/script><\/p>\n<p>And then build the container;<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\n$ docker-compose -d\r\n<\/pre>\n<p>Once everything has been built, go to the Kitematic window and you&#8217;ll see the WordPress container listed, click the setting tab and then Ports, where you&#8217;ll find the IP address, click that and it&#8217;ll automatically open the WordPress site.<\/p>\n<p>Once you finished you can click the stop button on the Kitematic window or start to initiate it.<\/p>\n<p><strong>Other Environments<\/strong><br \/>\nThere are alternatives besides Docker that you can choose the easiest one would be <a href=\"https:\/\/www.mamp.info\/\" target=\"_blank\">MAMP<\/a> (A slight warning there\u2019re a few system conflicts on El Capitan), another one would be <a href=\"https:\/\/roots.io\/trellis\/\" target=\"_blank\">Trellis<\/a> which is based on <a href=\"https:\/\/www.vagrantup.com\/\" target=\"_blank\">Vagrant<\/a> or if you&#8217;re adventurous you could install <a href=\"https:\/\/www.centos.org\/\" target=\"_blank\">Centos<\/a> and, of course, El Capitan comes with its own <a href=\"http:\/\/jason.pureconcepts.net\/2015\/10\/install-apache-php-mysql-mac-os-x-el-capitan\/\" target=\"_blank\">apache server<\/a>.<\/p>\n<p><strong>Ajax Page Transition<\/strong><br \/>\nThe fun part in developing WordPress \u2014well, relatively speaking\u2014 would be avoiding all the plugins peril, since a copious amount of it will bog down your site.<\/p>\n<p>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)<\/p>\n<p>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 <a href=\"https:\/\/codex.wordpress.org\/Plugin_API\/Action_Reference\/wp_enqueue_scripts\" target=\"_blank\">wp_enqueue_scripts<\/a> instead of wp_print_scripts.<\/p>\n<p>The system can be achieved with a simple Ajax and a hint of History API, have a look at the diagram below; <\/p>\n<p><img decoding=\"async\" src=\"http:\/\/i.imgur.com\/CTmI6Dh.png\" alt=\"diagram\" \/><\/p>\n<p>It&#8217;s pretty simple isn&#8217;t! Onwards with the code.<\/p>\n<p>First, you need to structure the template accordingly so it&#8217;ll be easier to extract and\/or overwrite the content later, like so;<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;body&gt;\r\n\r\n     &lt;!-- The content div would be used as a container --&gt;\r\n     &lt;div id=&quot;content&quot;&gt;\r\n          &lt;h1&gt;About Us&lt;\/h1&gt;\r\n          &lt;p&gt;Lorem ipsum..&lt;\/p&gt;\r\n     &lt;\/div&gt;\r\n\r\n&lt;\/body&gt;\r\n<\/pre>\n<p>Second, to change the URL path without refreshing the browser, utilize the history data.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\n\/\/ when the back button is pressed, each recorded history will be removed\r\n\/\/ this listener will listen to that event\r\nwindow.onpopstate = function(event) {\r\n   \/\/ Update whatever you have on the page\r\n    updatePage();\r\n}\r\n\r\n\/\/ This is just to illustrate the function\r\nfunction callPage(url, pageData) {\r\n\r\n  \/\/ If you're using old browser don't forget to add a fallback\r\n  history.pushState(pageData, pageData.title,  url);\r\n\r\n}\r\n\r\n\/\/ Trigger this method through button click\r\ncallPage(&quot;\/about\/&quot;, { item: { title: &quot;About us&quot; } });\r\n<\/pre>\n<p>There&#8217;s not much to it, you can read it more <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/History_API\" target=\"_blank\">here<\/a> if you want and if you need a fallback you can use <a href=\"https:\/\/github.com\/browserstate\/history.js\/\" target=\"_blank\">history.js<\/a>.<\/p>\n<p>Afterwards, call the page through Ajax.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction connectPage(url, data ) {\r\n\r\n    $.ajax(\r\n      \/\/ type: 'GET', \/\/ optional\r\n      url: url, \/\/ pass the page url\r\n      data: data \/\/ add this to pass data between content\r\n      cache: false, \/\/Setting cache to false will only work correctly with HEAD and GET requests. It works by appending &quot;_={timestamp}&quot; to the GET parameters\r\n      \/\/ dataType: 'html',  \/\/optional\r\n      success: function(data) {\r\n\r\n        if(data.length) {\r\n\r\n          \/\/ Handle Error\r\n          onError(&quot;Data empty&quot;);\r\n        }\r\n\r\n        \/\/ Handle success\r\n        onSuccess(data);\r\n\r\n      },\r\n      error: function(errorThrown) {\r\n\r\n        \/\/ Handle Error\r\n        onError(errorThrown);\r\n\r\n      }\r\n    )\r\n\r\n}\r\n\r\nconnectPage(&quot;\/about\/&quot;, {});\r\n<\/pre>\n<p>As you can see you probably could merge those two functions together.<\/p>\n<p>Once the data is extracted, the next step would be isolating and attaching the HTML content.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction onSuccess(data) {\r\n\r\n    data = data.split('id=&quot;content&quot;')[1]; \/\/ the ID name can be anything you want.\r\n    data = data.substring(data.indexOf('&gt;') + 1);\r\n\r\n    var depth   = 1,\r\n    output      = '';\r\n\r\n    while(depth &gt; 0) {\r\n      var temp = data.split('&lt;\/div&gt;')[0];\r\n      var i = 0;\r\n      var pos = temp.indexOf('&lt;div');\r\n\r\n      while(pos != -1) {\r\n        i++;\r\n        pos = temp.indexOf('&lt;div', pos + 1);\r\n      } \r\n\r\n\r\n      depth   = depth + i - 1;\r\n      output  = output + data.split('&lt;\/div&gt;')[0] + '&lt;\/div&gt;';\r\n      data    = data.substring(data.indexOf('&lt;\/div&gt;') + 6);\r\n     \r\n    }\r\n\r\n    \/\/ attach the HTML output\r\n    document.getElementById(&quot;content&quot;).innerHTML = output;\r\n\r\n    \/\/ Update Google Analytics\r\n    ga('set', { page: window.location.pathname })\r\n    ga('send', 'pageview')\r\n\r\n    \/\/ Update page\r\n    updatePage();\r\n\r\n}\r\n<\/pre>\n<p><strong>Retreiving Post with Nonce<\/strong><\/p>\n<p>By using nonce (number used once)  your site will be protected against cross-site request forgery. <\/p>\n<p>For instance, if we wanted to retrieve a certain post, then we could do something like this.<\/p>\n<p>Modify the Ajax call we had earlier.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nconnectPage(&quot;\/about\/&quot;, {\r\n  action: 'get_post_ajax',\r\n  postID: id, \/\/ The Wordrpess post ID\r\n  security: &lt;?php wp_create_nonce  ('blahblah'); ?&gt;\r\n});\r\n<\/pre>\n<p>Then on functions.php check for the value;<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n  function get_posts_ajax() {\r\n\r\n      if ( isset($_REQUEST) ) {\r\n\r\n          check_ajax_referer('blahblah', 'security' );\r\n\r\n          $post_id    = sanitize_text_field($_REQUEST['postID']);\r\n          $post_info  = get_post(intval($post_id));\r\n\r\n          $cat        = get_the_category(intval($post_id));\r\n          $cur_cat_ID = $cat[0]-&gt;cat_ID;\r\n          $args       = array(\r\n            'category'  =&gt; $cur_cat_ID,\r\n            'orderby'   =&gt; 'post_date',\r\n            'order'     =&gt; 'DESC'\r\n          );\r\n\r\n          $posts  = get_posts( $args );\r\n\r\n          wp_send_json(array(\r\n            'ID'                    =&gt; $post_info-&gt;ID,\r\n            'post_author'           =&gt; $post_info-&gt;post_author,\r\n            'post_date'             =&gt; $post_info-&gt;post_date,\r\n            'post_date_gmt'         =&gt; $post_info-&gt;post_date_gmt,\r\n            'post_content'          =&gt; $post_info-&gt;post_content,\r\n            'post_title'            =&gt; strtoupper($post_info-&gt;post_title),\r\n            'post_excerpt'          =&gt; $post_info-&gt;post_excerpt,\r\n            'post_status'           =&gt; $post_info-&gt;post_status,\r\n            'comment_status'        =&gt; $post_info-&gt;comment_status,\r\n            'ping_status'           =&gt; $post_info-&gt;ping_status,\r\n            'post_password'         =&gt; $post_info-&gt;post_password,\r\n            'post_name'             =&gt; $post_info-&gt;post_name,\r\n            'to_ping'               =&gt; $post_info-&gt;to_ping,\r\n            'pinged'                =&gt; $post_info-&gt;pinged,\r\n            'post_modified'         =&gt; $post_info-&gt;post_modified,\r\n            'post_modified_gmt'     =&gt; $post_info-&gt;post_modified_gmt,\r\n            'post_content_filtered' =&gt; $post_info-&gt;post_content_filtered,\r\n            'post_parent'           =&gt; $post_info-&gt;post_parent,\r\n            'guid'                  =&gt; $post_info-&gt;guid,\r\n            'menu_order'            =&gt; $post_info-&gt;menu_order,\r\n            'post_type'             =&gt; $post_info-&gt;post_type,\r\n            'post_mime_type'        =&gt; $post_info-&gt;post_mime_type,\r\n            'comment_count'         =&gt; $post_info-&gt;comment_count,\r\n            'filter'                =&gt; $post_info-&gt;filter\r\n            )\r\n          );\r\n\r\n      }\r\n\r\n      wp_die();\r\n  }\r\n<\/pre>\n<p><strong>Conclusion<\/strong><br \/>\nWhen working with WordPress the first thing that you always need to consider is the security aspect, its ubiquitousness attracts hacks, always follow the <a href=\"https:\/\/vip.wordpress.com\/documentation\/best-practices\/\" target=\"_blank\">best practice<\/a> (not guaranteed), learn about the <a href=\"https:\/\/www.hacksplaining.com\/\" target=\"_blank\">basic security hacks<\/a>,  implement <a href=\"https:\/\/www.google.com\/recaptcha\/intro\/index.html\" target=\"_blank\">re-captcha<\/a>, update the WordPress constantly, etc.<\/p>\n<p>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&#8217;t use it too much), is great for obnoxious client \ud83d\ude42 , but if speed is what you after then I suggest you try <a href=\"https:\/\/github.com\/ageitgey\/amplify\" target=\"_blank\">Amplify<\/a> or <a href=\"https:\/\/ghost.org\/\" target=\"_blank\">Ghost<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A slight detour here just wanted to talk about WordPress development \u2014not actually cutting edge\u2014 but since I&#8217;ve been working on a few WordPress projects lately I thought I&#8217;d share some of my tips, plus remember if you&#8217;re good at WordPress you could make a decent amount of \u00a5\u00a5\u00a5. Prerequisites This is my enviroment. Mac [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[186,36,193,192,59],"tags":[],"_links":{"self":[{"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=\/wp\/v2\/posts\/1583"}],"collection":[{"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1583"}],"version-history":[{"count":93,"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=\/wp\/v2\/posts\/1583\/revisions"}],"predecessor-version":[{"id":1773,"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=\/wp\/v2\/posts\/1583\/revisions\/1773"}],"wp:attachment":[{"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1583"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1583"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rahmat-hidayat.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1583"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}