<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Chris Klosowski</title><description>On eCommerce, software, and running a software business</description><link>https://chrisk.io/</link><language>en</language><item><title>The definitive guide to WordPress asset versioning</title><link>https://chrisk.io/posts/definitive-guide-wordpress-asset-versioning/</link><guid isPermaLink="true">https://chrisk.io/posts/definitive-guide-wordpress-asset-versioning/</guid><description>How and when to use the different versioning options of the WordPress asset registration/enqueueing functions wp_register_script and wp_register_style.</description><pubDate>Mon, 05 Jun 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Wether you are building a theme or plugin for WordPress, you will typically need to register and load your own Javascript or CSS file at some point. You do this by using the functions provided by WordPress core:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.wordpress.org/reference/functions/wp_register_style/&quot;&gt;wp_register_style&lt;/a&gt; - Registers a CSS file &lt;code&gt;wp_register_style( string $handle, string $src, array $deps = array(), string|bool|null $ver = false, string $media = &apos;all&apos; )&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.wordpress.org/reference/functions/wp_register_script/&quot;&gt;wp_register_script&lt;/a&gt; - Registers a Javascript source (either local or external) &lt;code&gt;wp_register_script( string $handle, string $src, array $deps = array(), string|bool|null $ver = false, bool $in_footer = false )&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Defining a version&lt;/h3&gt;
&lt;p&gt;Both of these functions allow you to define a source URL and a few other arguments, but today we&apos;re going to focus on the &lt;code&gt;$ver&lt;/code&gt; argument. The &lt;code&gt;$ver&lt;/code&gt; or &apos;Version&apos; of your script or style allows you to append a version of your choice as a query string, for instance, these are a few examples from this site:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;https://chrisk.io/wp-content/plugins/better-click-to-tweet/assets/css/styles.css?ver=3.0&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;https://chrisk.io/wp-content/plugins/easy-digital-downloads/templates/edd.min.css?ver=2.7.9&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Both of the above examples have version numbers appended that reference the currently installed version of those plugins.&lt;/p&gt;
&lt;h3&gt;Why do we version our assets?&lt;/h3&gt;
&lt;p&gt;Versioning your assets is super useful for &apos;busting cache&apos; when you release a new version. Modern browsers will cache CSS and JavaScript files locally to the visitor if the URL to the file is the same as it was the last visit. By appending a new version number when you update your theme or plugin, you&apos;re effectively telling all visitors to the site that a new version of the asset is available, and it should re-download it. This prevents you from having to ask the dreaded question of &quot;Did you clear your cache?&quot;&lt;/p&gt;
&lt;h3&gt;What if I don&apos;t define a version&lt;/h3&gt;
&lt;p&gt;You may also, from time to time, see plugins and themes have their scripts or styles contain a version that match the currently installed WordPress version, like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;https://chrisk.io/wp-content/plugins/plugin-example/style.min.css?ver=4.7.5&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In this case, the developer would have chosen to not define a version when registering their styles or scripts. By providing no version, WordPress will append it&apos;s own version.&lt;/p&gt;
&lt;h3&gt;Should we version external resource?&lt;/h3&gt;
&lt;p&gt;So what about assets that are &lt;em&gt;external&lt;/em&gt; to your server? Things like 3rd party JavaScript resources. For example the Stripe payment gateway has store owners include a JavaScript file directly from their own servers. In this case you want &lt;strong&gt;NO&lt;/strong&gt; version to be appended. Not your plugin&apos;s, theme&apos;s, or WordPress&apos;s version. In this case you must pass in &lt;code&gt;null&lt;/code&gt; as the version.&lt;/p&gt;
&lt;h4&gt;Ways do define your versions&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;String (Ex: &apos;2.7.9&apos;) - Results in ../style.css?ver=2.7.9&lt;/li&gt;
&lt;li&gt;&lt;code&gt;false&lt;/code&gt; - Results in ../style.css?ver=4.7.5 (where 4.7.5 will be the current WordPress version)&lt;/li&gt;
&lt;li&gt;Not defined - Results in ../style.css?ver=4.7.5 (where 4.7.5 will be the current WordPress version)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;null&lt;/code&gt; - Results in ../style.css&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Why not use something other than the version?&lt;/h3&gt;
&lt;p&gt;There have been a few times that a person has asked me why not use something like a timestamp or the last time the file was changed to allow for version busting. While these do work to make sure the user isn&apos;t getting a cached version, there are a few issues that arise.&lt;/p&gt;
&lt;h4&gt;Using Timestamps&lt;/h4&gt;
&lt;p&gt;When you use the current timestamp to set your version, that means every time someone visits your page, they&apos;ll have to re-download your assets, since even 1 second later, your timestamp has changed from the last visit. While this helps by never having a cached version of the file, it can hurt your performance by making the user&apos;s browser download files it&apos;s previously downloaded, even though they have not changed.&lt;/p&gt;
&lt;h4&gt;Using file modification time&lt;/h4&gt;
&lt;p&gt;In the current space of hosting and multi-server configurations (even in some of the shared hosting world), file modification time could cause similar issues to timestamps. PHP has a function that allows you to get the last time a file was modified, and therefore, that would be the last time the CSS or JS file changed, in theory. All it really means is that&apos;s the last time the file was modified on your servers. If you have a multi-server environment, each server could have a slightly different time that the file was modified, and therefore it&apos;s possible that on subsequent visits to your site, a visitor would request the file from a different server and thus get a different &apos;last modified&apos; time, requiring them to download the file again, even though it&apos;s the exact same file they just requested.&lt;/p&gt;
</content:encoded></item><item><title>Adding progress bars to your WP-CLI processes.</title><link>https://chrisk.io/posts/adding-progress-bars-wp-cli-processes/</link><guid isPermaLink="true">https://chrisk.io/posts/adding-progress-bars-wp-cli-processes/</guid><description>Learn how to add a progress bar to your WPCLI commands</description><pubDate>Fri, 03 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As of late, I&apos;ve found myself doing quite a few things via the command line with &lt;a href=&quot;http://wp-cli.org/&quot;&gt;WP-CLI&lt;/a&gt;. If you&apos;ve never used it before, it&apos;s an extremely powerful command line interface for interacting with your WordPress installation. It comes bundled with some great utilities to help you out, including a WPCLI progress bar, but we&apos;ll get to that in a minute.&lt;/p&gt;
&lt;p&gt;Where it becomes extremely powerful is with tasks that can cause a web based interface to timeout or reach the max execution times. I have found it very helpful when running migration, import, and export scripts. If you&apos;ve ever executed a long running task in the command line, you&apos;ve felt the pain of thinking:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Is it still going? Did it break? What&apos;s happening?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;Enter...the progress bar&lt;/h4&gt;
&lt;p&gt;WP-CLI has an awesome built in method that allows you to output a progress bar, complete with the percentages, running time, and estimated time to completion.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/wp-cli-progress-bar-example.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The code to make this happen is surprisingly simple. It consists of 3 lines:&lt;/p&gt;
&lt;p&gt;First you define what the text will be in front of the progress bar, and the total number of items to complete.&lt;br /&gt;
&lt;code&gt;$progress = \WP_CLI\Utils\make_progress_bar( &apos;Progress Bar&apos;, $total );&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Next, during each step of your loop, you &lt;em&gt;tick&lt;/em&gt; the progress bar.&lt;br /&gt;
&lt;code&gt;$progress-&amp;gt;tick();&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;After your loop is complete, you &lt;em&gt;finish&lt;/em&gt; the progress bar&lt;br /&gt;
&lt;code&gt;$progress-&amp;gt;finish();&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;Example Plugin&lt;/h4&gt;
&lt;p&gt;[purchase_link id=&quot;3150&quot; text=&quot;Get Project File&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;/p&gt;
&lt;p&gt;https://gist.github.com/cklosowski/1aba412c4476c8d6fb5107eba9f90741&lt;/p&gt;
&lt;p&gt;[purchase_link id=&quot;3150&quot; text=&quot;Get Project File&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;/p&gt;
</content:encoded></item><item><title>Becoming a Better Debugger</title><link>https://chrisk.io/posts/becoming-better-debugger/</link><guid isPermaLink="true">https://chrisk.io/posts/becoming-better-debugger/</guid><description>Debugging software is the bane of existence for most developers. Once you can use a few key strategies though, it becomes something you love to do.</description><pubDate>Fri, 10 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Debugging. The ultimate equalizer when it comes to developers. The ability to identify, diagnose, fix, test, and deploy a patch to an elusive bug is the ultimate adrenaline rush for a developer...right? It cannot be &lt;em&gt;just me&lt;/em&gt;! So how can you become a better debugger?&lt;/p&gt;
&lt;h3&gt;Debugging is like being a sniper&lt;/h3&gt;
&lt;p&gt;Just as being a sniper takes immense training and instruction, as does becoming a good developer. Trained snipers have two phrases that &lt;strong&gt;I like to think&lt;/strong&gt; relate to debugging software pretty well.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DOPE - An acronym for &quot;Data on Previous Engagement&quot;&lt;/li&gt;
&lt;li&gt;One Shot. One Kill.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Data. Data. Data.&lt;/h3&gt;
&lt;h4&gt;The deal with DOPE&lt;/h4&gt;
&lt;p&gt;Snipers use their &quot;&lt;em&gt;DOPE&lt;/em&gt;&quot; to make adjustments to their next shot, based off the data they observed from their previous shots. Seeing how the wind affected the trajectory, how the humidity weighed down the projectile, or even (at extremely long distances), how the rotation of the Earth affected the outcome. The point is, seeing the affects of the previous engagements helps them make an informed decision about the next move.&lt;/p&gt;
&lt;h4&gt;Experience matters&lt;/h4&gt;
&lt;p&gt;As your development career advances, so to will your experiences and chance to witness the outcomes of some of your decisions. Through your efforts to always produce stellar software, you will have some failures or unforeseen side affects. At times it&apos;s easy to try and ignore those as &quot;one offs&quot; or &quot;edge cases&quot;, but it&apos;s important to remember these moments, as they can help you identify things &quot;not to do&quot; when you&apos;re working on a hot fix for a serious production bug.&lt;/p&gt;
&lt;h4&gt;Take &quot;notes&quot;&lt;/h4&gt;
&lt;p&gt;Whether you are the person who carries around a trendy Moleskin notebook, uses Evernote, or has the eidetic memory like Dr. Spencer Reed, keeping a note about a &quot;weird bug&quot; you saw is beneficial to your future debugging. By doing so, you can shorten the time between identification to resolution, simply by remembering what caused a previous bug, and being able to identify if it matches a pattern you&apos;ve seen before.&lt;/p&gt;
&lt;p&gt;Notes don&apos;t have to be physical. The key is that you are not just fixing the bug, but understanding why the bug happened in the first place. Usually error messages can be extremely helpful, but every now and then you get an error message you just don&apos;t understand why it happens. For instance:&lt;/p&gt;
&lt;p&gt;From time to time, in the WordPress ecosystem, you&apos;ll see a site where the RSS Feeds fail XML validation for an unexpected character on line 1, character 1. This can leave many people stumped...and a google search shows lots of results, with lots of different suggestions.&lt;/p&gt;
&lt;p&gt;Usually though, what it means is that a plugin or theme has an extra blank line at the end of a PHP file...like so:&lt;/p&gt;
&lt;p&gt;https://gist.github.com/cklosowski/e6d9c8a59aa67ffc32d1fdab149c7958&lt;/p&gt;
&lt;p&gt;I won&apos;t go into the specifics here of why it happens exactly, but the important thing is that when I see that error, the first thing I look for is PHP files with blank lines at the end. This is the type of thing that you should be taking &apos;mental note&apos; of. It&apos;s the Data from Previous Engagements, like mentioned above.&lt;/p&gt;
&lt;h4&gt;There is no &quot;coincidence&quot;&lt;/h4&gt;
&lt;p&gt;If you&apos;ve got a pesky bug that seems to be hard to replicate, but more than 1 person has seen it, odds are, you have a bug. It may not be a common bug, but based off the data, there is a bug. Your &lt;em&gt;DOPE&lt;/em&gt; doesn&apos;t just have to come from you, in the case of development. You can use the data from other people using your software to widen the scope of your bug hunt.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;When debugging, there is no such thing as coincidence.&quot; username=&quot;cklosowski&quot;]&lt;/p&gt;
&lt;h3&gt;You only get one shot&lt;/h3&gt;
&lt;h4&gt;Ok that&apos;s a little dramatic...&lt;/h4&gt;
&lt;p&gt;...but let&apos;s be honest. Finding a bug, fixing it, releasing it, only to find out that it either didn&apos;t fix it, or made matters worse...is no fun. This is a situation that no one likes to be in, and it&apos;s avoidable through a few practices.&lt;/p&gt;
&lt;h4&gt;ABaT&lt;/h4&gt;
&lt;p&gt;Always be (automated) testing. If you aren&apos;t writing unit tests for the bugs you find, then you need to be. I&apos;ll admit, I&apos;m not always doing it...but I should be. If there is a bug that&apos;s big enough to force a deployment, you should be writing a unit test to make sure you&apos;ve fixed it. This is for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;An automated test is better at logic than a human&lt;/li&gt;
&lt;li&gt;You never want to reintroduce a failure&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By adding a unit test for a production release level bug, you&apos;re making sure that in the future, you don&apos;t accidentally re-introduce the bug. Things can get hectic during an emergency deployment, and sometimes things get missed, like rolling a hot fix back into the development version of the app.&lt;/p&gt;
&lt;h4&gt;Reputation is hard to recover&lt;/h4&gt;
&lt;p&gt;As someone who writes software that people&apos;s businesses depend on, &lt;a href=&quot;https://chrisk.io/protect-all-the-reputations/&quot;&gt;reputation management does not fall short on me&lt;/a&gt;. When I introduce a bug, it introduces a bug to my &quot;customer&apos;s customers&quot;. This is why I think it&apos;s extremely important to have the &apos;one shot&apos; approach to a bug release. Making sure it is &lt;strong&gt;done, and done right&lt;/strong&gt; will go much further than &lt;em&gt;having it done now&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;What&apos;s your most memorable bug?&lt;/h3&gt;
&lt;p&gt;We&apos;ve all had that bug that we will never forget...what&apos;s yours? Mine, you ask? Well...mine was so epic, it was &lt;a href=&quot;https://hardrefresh.audio/episodes/the-phantom-subscriptions/&quot;&gt;the topic of an entire podcast episode&lt;/a&gt;, so don&apos;t feel bad. In short a single line of code would have prevented 400 lines to patch a bug that was assigning incorrect payment data to customers.&lt;/p&gt;
</content:encoded></item><item><title>Conditionally add CSS classes to WordPress Widgets</title><link>https://chrisk.io/posts/conditionally-add-css-classes-to-wordpress-widgets/</link><guid isPermaLink="true">https://chrisk.io/posts/conditionally-add-css-classes-to-wordpress-widgets/</guid><description>How to conditionally add CSS classes to a WordPress Widget wrapper element, based off it&apos;s instance settings.</description><pubDate>Thu, 09 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently, while working on the next upcoming release of &lt;a href=&quot;https://chrisk.io/i/edd&quot;&gt;Easy Digital Downloads&lt;/a&gt;, we were challenged with a unique request. The goal, was to hide our Cart Widget when the cart was empty, but show it when the cart had items added to it, then re-hide the widget if it were emptied again. All well and good, but it had to be something that was on a per-instance basis, and happen without a page refresh. Meaning, you could have multiple cart widgets on a page, and they could behave independently.&lt;/p&gt;
&lt;h3&gt;Easy Peasy....ish&lt;/h3&gt;
&lt;p&gt;If you&apos;ve ever dealt with Widgets in WordPress, then you know as well as I do, no problem, we&apos;ll just do some logic within the `widget` method of the PHP Class we built, and determine if the cart is empty, add a few CSS classes to a new HTML element that wraps the content, and we&apos;re good.&lt;/p&gt;
&lt;p&gt;Or so I thought...&lt;/p&gt;
&lt;p&gt;It was quickly pointed out that the `widget` method doesn&apos;t actually contain the &apos;wrapper&apos; element that WordPress renders your widget within, just the internal content. Consequently, by hiding the content in the widget, we left the wrapper elements visible, and those are what Theme Developers use sometimes, causing a problem. So, back to the drawing board.&lt;/p&gt;
&lt;h3&gt;Digging a little deeper&lt;/h3&gt;
&lt;p&gt;The original request mentioned a filter named &lt;code&gt;dynamic_sidebar_params&lt;/code&gt;, and this filter was a great idea, except one thing, I couldn&apos;t figure out how to access the specific widget instance&apos;s settings, to know if we &lt;em&gt;should&lt;/em&gt; hide this instance when empty (and do so by adding CSS classes to the wrapper).&lt;/p&gt;
&lt;p&gt;Or so I thought....again...&lt;/p&gt;
&lt;h3&gt;The solution&lt;/h3&gt;
&lt;p&gt;It turns out, there are a few methods of the base `WP_Widget` class that you can use to get some instance settings, that I wasn&apos;t aware of. Below is the basic outline of a widget class that includes a title option as well as an option to add a CSS Class to the widget wrapper, using the settings:&lt;/p&gt;
&lt;p&gt;https://gist.github.com/cklosowski/f473f5234fb3cfe719d7f7a0c2edc5fa&lt;/p&gt;
&lt;h3&gt;Breaking it all down&lt;/h3&gt;
&lt;p&gt;Most of this will look familiar if you&apos;ve written a widget before, but the key is the inclusion of the &lt;code&gt;widget_class&lt;/code&gt; method, and the filter hooking into &lt;code&gt;dynamic_sidebar_params&lt;/code&gt;. What this does, is lets us access part of the Widget that wraps it within the theme, before the output of the widget contents.&lt;/p&gt;
&lt;p&gt;This filter will run on each widget loaded on the page, so we first need to make sure that we&apos;re looking at an instance of our own widget:&lt;br /&gt;
&lt;code&gt;if ( strpos( $params[0][&apos;widget_id&apos;], &apos;ck_example_widget&apos; ) !== false ) {&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;After that we get all the settings related to this specific instance of the Widget (since you can have multiple instances of the same widget in some cases).&lt;br /&gt;
&lt;code&gt;$instance_settings = $all_settings[ $instance_id ];&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Once there, we see if the option to add the class was checked:&lt;br /&gt;
&lt;code&gt;if ( ! empty( $instance_settings[&apos;add_wrapper_class&apos;] ) ) {&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And if we&apos;ve checked it, perform a regular expression search to add in our new class we want to add to the wrapper.&lt;/p&gt;
&lt;h4&gt;Hope this helps out!&lt;/h4&gt;
</content:encoded></item><item><title>3 Ways to reduce your bounce rate as a technical blogger</title><link>https://chrisk.io/posts/3-ways-reduce-bounce-rate-technical-blogger/</link><guid isPermaLink="true">https://chrisk.io/posts/3-ways-reduce-bounce-rate-technical-blogger/</guid><description>Bounce rate is a problem that plagues highly technical blog posts, these are some ways you can help reduce bounce rates.</description><pubDate>Thu, 08 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As someone who writes on some highly technical topics, it&apos;s no surprise when traffic comes in from Google via searches. Writing about solving a technical solution is a &lt;strong&gt;fantastic&lt;/strong&gt; way to bring in new traffic. By using common error messages and phrases, you can capture people looking to solve the same problem you &lt;em&gt;already&lt;/em&gt; did. There is a downside to this highly technical and targeted traffic. It usually has a high bounce rate.This is a challenge that actually hits my own site pretty heavily as I write on things ranging from &lt;a href=&quot;https://chrisk.io/using-easy-digital-downloads-software-licensing-api-gatekeeper/&quot;&gt;interacting with APIs&lt;/a&gt; all the way through &lt;a href=&quot;https://chrisk.io/how-writing-one-plugin-changed-my-lifestyle/&quot;&gt;how life changing working in open source can become&lt;/a&gt;. If you aren&apos;t familiar with what the bounce rate statistic is, it refers to:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;the percentage of visitors to a particular website who navigate away from the site after viewing only one page.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Why does technical traffic bounce?&lt;/h3&gt;
&lt;p&gt;Think about the last time you used Google to solve a development problem...or if you aren&apos;t a developer, needed to fix something. Typically you struggle at it on your own until you admit defeat, open a new tab or grab your phone, and search for the answer to your problem. You will try out the first 2-3 results to see which you like best, close out the ones you don&apos;t need, and then follow your found solution. When you finish fixing your issue, you close that tab, and go on your way. Congratulations, you just became a bounce statistic.&lt;/p&gt;
&lt;h3&gt;Highly Technical posts don&apos;t retain visitors&lt;/h3&gt;
&lt;p&gt;The reason these types of posts that contain code or step-by-step solutions end in a bounce is...&lt;strong&gt;&lt;em&gt;it did it&apos;s job&lt;/em&gt;&lt;/strong&gt;. When you write good technical content, it solves a problem and the user can go on with their task. There is nothing wrong with this type of content, as it does a couple things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Brings in targeted traffic&lt;/li&gt;
&lt;li&gt;Helps establish you as an expert in the field&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So how can we tackle this problem...&lt;/p&gt;
&lt;h3&gt;1. Diversify your content&lt;/h3&gt;
&lt;p&gt;You can write posts about code and solving technical issues until the cows come home. Until you can diversify you content strategy to contain a mix of highly technical and more abstract conceptual topics, you&apos;ll be stuck with a higher bounce rate. You can start by alternating your post schedule to flip between a conceptual piece, and then a technical piece. Obviously, you have to be somewhat flexible here, but it&apos;s a good start.&lt;/p&gt;
&lt;h3&gt;2. Use internal linking&lt;/h3&gt;
&lt;p&gt;Internal linking is when you link from one blog post on your site to another. This not only builds a good internal roadmap to the user, but also is a great way to generate multiple page views per visit. You can go overkill here, however. Too many internal links and the content becomes unreadable. Typically one internal link for every 200-300 words is ideal.&lt;/p&gt;
&lt;h3&gt;3. Highlight your primary categories&lt;/h3&gt;
&lt;p&gt;Your site may have 5 or 6 categories on it, but odds are you find yourself posting in 2 or 3 primary categories more often than the others. One way to keep traffic on the site is to make a good &apos;Call to Action&apos; or &apos;Visual Cue&apos; to what your main focus is as a content creator, and drive them towards these topics. This can be as simple as adding a small list of your main topics to your sidebar, or adding them as a primary navigation item. By adding them to these areas, you&apos;re identifying them as a sort of &apos;Table of Contents&apos; as to what value you can provide to the visitor immediately.&lt;/p&gt;
&lt;h3&gt;Q&amp;amp;A&lt;/h3&gt;
&lt;p&gt;What&apos;s a challenge &lt;em&gt;you&lt;/em&gt; face with your highly technical content? What steps have you taken, or are you taking to convert this traffic into repeat visitors?&lt;/p&gt;
</content:encoded></item><item><title>Make a branch from a Pull Request on GitHub</title><link>https://chrisk.io/posts/make-branch-pull-request-github/</link><guid isPermaLink="true">https://chrisk.io/posts/make-branch-pull-request-github/</guid><description>How to make changes to a GitHub Pull Request</description><pubDate>Fri, 11 Nov 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Many times, as an open source project maintainer, I&apos;m tasked with reviewing pull requests that community members have contributed to our project. It&apos;s honestly one of my favorite things to do. Seeing community collaboration on projects is awesome, and really helps me feel a purpose to what I do on a day to day basis. While any pull request is typically welcome, there are times when slight edits are needed to meet project guidelines or coding standards.&lt;/p&gt;
&lt;h3&gt;Edit a pull request and maintain commit history&lt;/h3&gt;
&lt;p&gt;The worst thing I could do as a maintainer is reject someone&apos;s code on they whitespace issues alone. I&apos;d love to have the whitespace perfect, but as long as the code works and achieves the task in a manor I feel adequate, whitespace changes or docblocs should not matter.&lt;/p&gt;
&lt;p&gt;The key here though, is I shouldn&apos;t lose someone&apos;s commit history, since they deserve credit for the initial work they&apos;ve done. So here&apos;s how I handle this.&lt;/p&gt;
&lt;p&gt;First, if an issue doesn&apos;t exist for the pull request I create one. That&apos;s important later.&lt;/p&gt;
&lt;p&gt;We&apos;ll assume 2 things here in my code:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Pull Request number is &lt;code&gt;123&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The Issue number is &lt;code&gt;567&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;git fetch origin pull/123/head:pull/123
git checkout pull/123
git checkout -b issue/567 pull/123
// Make changes
git push origin issue/567&lt;/p&gt;
&lt;p&gt;From that point you can close the original Pull Request in 123 without merging, and after making your edits and pushing to the &lt;code&gt;issue/567&lt;/code&gt; branch, create a new pull request. This new pull request, will have all the necessary commit history to retain credit for the original Pull Request author.&lt;/p&gt;
</content:encoded></item><item><title>How becoming a parent has made me a better developer</title><link>https://chrisk.io/posts/how-becoming-a-parent-has-made-me-a-better-developer/</link><guid isPermaLink="true">https://chrisk.io/posts/how-becoming-a-parent-has-made-me-a-better-developer/</guid><description>The life of a parent/software developer has many challenges, but oddly enough, not that unique to just parenting. These are a few things that I&apos;ve learned.</description><pubDate>Mon, 24 Oct 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Straight up disclaimer:&lt;/strong&gt; This isn&apos;t about being a parent. It&apos;s about being a software developer, so stick with me here :)&lt;/p&gt;
&lt;p&gt;3 years ago, things changed. For the better. I became a father. Being that this was my first child, you can bet there was a lot of apprehension. I&apos;d never even been around a new born for more than a few minutes, and now I was partly responsible for keeping one alive. Things got intense. Fast forward a few years and things are very different. Sleeping habits, schedules, meals...all that stuff is just a variable. Every day is different. We never know what&apos;s going to happen that day. All this &lt;em&gt;instability&lt;/em&gt; has taught me a few things though. These few things, after some time to reflect, prove to be very important in my life as a career software developer though...and today, you get to benefit from my sleepless nights with kids.&lt;/p&gt;
&lt;h3&gt;Write smaller, single-use functions&lt;/h3&gt;
&lt;p&gt;Since time is valuable, and there is no shortage of distractions, writing small functions that do one thing, and are easy to read are crucial to success. Kids or not, you have enough distractions in your life that pull your attention away from the project you are working on. Keeping things small and concise means you can quickly write complete sets of functionality, rather than a large function that, if you step away from, you&apos;ll get lost in. This isn&apos;t just about time management either, functions that do one thing, are easier to write unit tests for.&lt;/p&gt;
&lt;h3&gt;Budget time for short breaks&lt;/h3&gt;
&lt;p&gt;Trying to sit down for 8 hours solid and write code just simply isn&apos;t attainable. Not even without diaper changes and family lunch time. Focusing on a single task for that long takes it&apos;s tole on you mentally and physically. I typically find that stepping away from my desk for a quick 5-10 minute break every 60-90 minutes helps with my focus and energy levels. Refill your coffee, take a bathroom break, change a diaper, or just walk around the building once. The key here is, your mind doesn&apos;t stop thinking about work, but you&apos;re removing yourself from the ability to sit down and write code. This causes your brain to have to think abstractly, which helps you work things out logistically in your head, before going further with your development process. For more information on this type of time management, you should check out the &lt;a href=&quot;https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=3&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=0ahUKEwi1mYKBn-bPAhVHz2MKHUl3CqUQFggrMAI&amp;amp;url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FPomodoro_Technique&amp;amp;usg=AFQjCNEcNK-woTV-MpzRR0ilVXA1DnbXxQ&amp;amp;sig2=7cJ9TX1TRU2V-hkYTuV6IQ&quot;&gt;Pomodoro Technique&lt;/a&gt; which uses a similar concept.&lt;/p&gt;
&lt;h3&gt;Consistency Matters&lt;/h3&gt;
&lt;p&gt;Consistency in the way you name functions, variables, classes, and files is critical to any developers success. In your issue management labels and processing, and in your commit messages. Just keeping things consistant, you reduce your &apos;spin up&apos; time when changing focus, which is more efficient. By using similar patterns in your code, it allows you to anticipate function names, classes, and where code is. You can see a little more on this topic in my slides from a presentation I did at a local developer meetup: http://www.slideshare.net/cklosowski/reduce-reuse-refactor-67391915&lt;/p&gt;
&lt;h3&gt;It&apos;s all about time management&lt;/h3&gt;
&lt;p&gt;As I said in the &apos;disclaimer&apos;...it&apos;s about development, not parenting. Parenting just urged these work habits onto me in a way I didn&apos;t expect, but with results that I found were a net positive in my work flow. Obviously parenthood and life changes look different on every person, but I think if you take a step back and try and make your work life &lt;em&gt;flow&lt;/em&gt; with your work style, you&apos;ll be much more productive and happy with the work you are doing.&lt;/p&gt;
&lt;p&gt;What is &lt;strong&gt;&lt;em&gt;your&lt;/em&gt;&lt;/strong&gt; go-to method of keeping yourself on task, and productive in the midst of distraction?&lt;/p&gt;
</content:encoded></item><item><title>3 Things More Important than the Programming Languages You Know</title><link>https://chrisk.io/posts/3-things-important-programming-languages-know/</link><guid isPermaLink="true">https://chrisk.io/posts/3-things-important-programming-languages-know/</guid><description>Knowing where to get started in software development can be tricky. Here are a few tips I give newcomers looking to make waves.</description><pubDate>Mon, 29 Aug 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As someone who tends to mentor and talk shop with people wanting to start a career in software development, the most common question I hear is “What language(s) should I learn to land a job?” It’s a question that makes sense if you think about it. From an outside perspective to the industry, picking the right language seems like it could make or break your career. The reality is, that there are plenty of things more important than what languages you know. In an effort to not overwhelm people, I usually stick to 3 things that are far more important than picking a language.&lt;/p&gt;
&lt;h3&gt;Show you have the ability to learn&lt;/h3&gt;
&lt;p&gt;Being a software developer is by and large about being flexible and being able to shift with the trends and changes in the industry. Not just at the human level, but at the code and platform levels as well. Things can be the hot new platform one year, and replaced the next. It’s just the way it works. Because the ecosystem is ever changing, so must we be as developers. The funny thing about development is that while syntax changes from language to language, the overall concepts and patterns are very similar between them. Prove that you can learn quickly, and have the willingness to take it upon yourself to learn by taking on role that enable this.&lt;/p&gt;
&lt;p&gt;See my &lt;a href=&quot;https://chrisk.io/must-books-software-development/&quot;&gt;suggested reading&lt;/a&gt; for anyone in software development&lt;/p&gt;
&lt;h3&gt;Deploy and/or Contribute&lt;/h3&gt;
&lt;p&gt;This all starts with one thing, showing your overall understanding of development. These days, it’s so easy to do with services like GitHub. The ability to quickly and easily share all the work you’ve published publicly is an often overlooked asset. You can have as many years of development that you want, but if it’s all private has only been for your own private use, it’s hard to consider that ‘experience’ when applying for jobs. By contributing to other open source projects on GitHub, or putting your own work up for collaboration, you can easily show your abilities.&lt;/p&gt;
&lt;p&gt;One of the other things people typically fail to recognize is that writing code for yourself, and writing code for production, typically corporate, environments are two completely different things. There is a level of ‘error handling’ that typically goes into production code. The ‘happy path’ isn’t the only solution and performance is scrutinized.&lt;/p&gt;
&lt;p&gt;Does that mean personal projects aren’t wroth anything? By all means, &lt;strong&gt;no&lt;/strong&gt;! It just means that when a company is looking for developers, they want to see that they can produce for other companies similar to theirs. Haven’t gotten any other paid gigs? That’s cool, contribute back to open source somehow. Show that you’ve got the ability for your ideas and code to make it into a popular open source project like WordPress or some Node Modules.&lt;/p&gt;
&lt;p&gt;If you are new to contributing to an open source project, it can be a bit intimidating, but I wrote &lt;a href=&quot;https://chrisk.io/coding-in-someone-elses-kitchen/&quot;&gt;a few tips&lt;/a&gt; on some things to keep in mind.&lt;/p&gt;
&lt;h3&gt;It&apos;s ok to be wrong, or not know&lt;/h3&gt;
&lt;p&gt;There are two things that any good developer can admit:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;They don’t know everything.&lt;/li&gt;
&lt;li&gt;There are bugs in their code, somewhere.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first of these is super important. You’re never expected to know everything there ever is to know about development. That’s just asinine. The important part is how you respond when confronted with a question or task that you don’t know. Some people simply shut down and in some cases deny it’s possibility. After many times of being the fool, I learned one thing.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;&apos;I don&apos;t know, yet&apos; is a perfectly acceptable answer.&quot; username=&quot;cklosowski&quot; nofollow=&quot;yes&quot;]&lt;/p&gt;
&lt;p&gt;Someone in a position to ask a question that would warrant this type of answer will be perfectly happy waiting for you do research and answer the question accurately. And most importantly, the word &lt;strong&gt;&lt;em&gt;&quot;yet&quot;&lt;/em&gt;&lt;/strong&gt;. This implies a willingness to learn. It’s ok not to know everything immediately, and again, leads us back the the first point of showing you can learn. Funny how it always ends up back there doesn’t it? The crazy part is...you are never alone in learning. Using crowd-sourced sites like StackOverflow aren&apos;t cheating, they&apos;re learning. You don&apos;t have to sit in your bubble all day and struggling trying to solve a complex problem alone. Posing a question to the community, or finding an existing question that suites your needs is a completely acceptable solution these days.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;So you can see, so much of being a good software developer is more about how you can grow and produce good work, than what languages you know. Much like any other skill, the more time you spend doing it the right way, the better the end product will be.&lt;/p&gt;
&lt;h5&gt;How about you? What&apos;s one thing you find more important than then languages you know?&lt;/h5&gt;
</content:encoded></item><item><title>Inspiration vs Motivation: Being honest with yourself</title><link>https://chrisk.io/posts/inspiration-vs-motivation-honest/</link><guid isPermaLink="true">https://chrisk.io/posts/inspiration-vs-motivation-honest/</guid><description>A little self discovery on whether you look to someone for inspiration or motivation, and what these two terms mean when it comes to your success.</description><pubDate>Thu, 07 Jul 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ever sit there and mindlessly scroll through your Twitter or Instagram accounts and minutes later, feel like you got nothing out of that? Happens to all of us, but recently I ended up having a bit of a realization as I looked through my timeline.&lt;/p&gt;
&lt;p&gt;Like most, there are a large number of people that I follow on my social media profiles that I do not know, personally, but I love seeing what they’ve achieved and their lifestyle. I know who they are, that they exist, what they are about (at least from an outward perspective), but I don’t know them as people. I don’t know what makes them tick (or tock). I’m not immediately aware of any inner struggles they may have had or are having, unless they talk about them. I truly don’t know how they got to where they are.&lt;/p&gt;
&lt;p&gt;There are other accounts, however, that I know &lt;strong&gt;&lt;em&gt;exactly how&lt;/em&gt;&lt;/strong&gt; they got to where they currently stand. They talk about it openly via social media and articles they’ve written. While I may not know them personally, they’ve gone out of their way to give me a little insight into what makes them keep going.&lt;/p&gt;
&lt;p&gt;I like to classify both of these perspectives into two categories:&lt;br /&gt;
Motivation and Inspiration&lt;br /&gt;
&lt;em&gt;Motivation&lt;/em&gt; shows you &lt;strong&gt;&lt;em&gt;what is achievable&lt;/em&gt;&lt;/strong&gt;.&lt;br /&gt;
&lt;em&gt;Inspiration&lt;/em&gt; shows you &lt;strong&gt;&lt;em&gt;the process of achieving&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Personally, I’m far more inspired and motivated by people who show me not only where they are, but how they got there, and what actions they took along the way. The reason is, if they share the how, you know a little about who they are as people, and if they are someone you want as an inspiration and motivator.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;The story of how you get there is just as important as getting there itself.&quot; username=&quot;cklosowski&quot;]&lt;/p&gt;
&lt;h4&gt;Leaving a trail of pride&lt;/h4&gt;
&lt;p&gt;I’ve always been inspired with sports stories. I think that’s why any “30 for 30” documentary that ESPN drops into Netflix ends up in my queue. The reason is pretty simple, I enjoy seeing the ‘how’ of the end result. Seeing all the hard work someone puts in to achieve their dream. Seeing the decisions made in the past and how they affect the future. I think it’s something that, while very apparent in athletics, is equally as important in business and life in general. How you approach each challenge in your life on the way to achieving your goal is part of your story. It can do far more to make what you do inspirational than reading the end result, in all honesty.&lt;/p&gt;
</content:encoded></item><item><title>Local WordPress development with Pressmatic. A Review.</title><link>https://chrisk.io/posts/local-wordpress-development-pressmatic-review/</link><guid isPermaLink="true">https://chrisk.io/posts/local-wordpress-development-pressmatic-review/</guid><description>Full disclosure: I was an early beta tester for Pressmatic and was provided a license key for testing purposes. Screenshots and information in this post may…</description><pubDate>Sat, 02 Jul 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Full disclosure: I was an early beta tester for &lt;a href=&quot;https://chrisk.io/i/pressmatic&quot;&gt;Pressmatic&lt;/a&gt; and was provided a license key for testing purposes. Screenshots and information in this post may change as the software changes, but this is my 100% honest opinion of the product.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Pressmatic has been acquired by the hosting provider Flywheel, and renamed &quot;Local by Flywheel&quot;. It&apos;s also been made &lt;a href=&quot;https://local.getflywheel.com/&quot;&gt;freely available&lt;/a&gt;! The rest of this review still holds fairly accurate as the product was virtually unchanged upon acquisition.&lt;/p&gt;
&lt;p&gt;My history with development environments is probably like most PHP developers. Always finding something that got us most of the way there, only to have a few shortcomings (or a lot in some cases) that just didn&apos;t make it the most efficient of all work flows. I&apos;ve either used or purchased close to 5 environments in the past few years, including MAMP Pro, Vagrant configurations, DesktopServer, XAAMP, and even just the local versions of the binaries installed with OS X. None of them met my needs to the fullest. MAMP Pro was &lt;em&gt;very&lt;/em&gt; close until payment gateways started requiring strong encryption to talk to their APIs (yay!), and MAMP Pro ships with Apache 2.2, which doesn&apos;t support this protocol (TLS 1.2).&lt;/p&gt;
&lt;h4&gt;Enter Pressmatic&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2016-07-02-at-8.36.28-AM.png&quot; alt=&quot;pressmatic-review-main-view&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I was hit up by a friend already in the testing group to join in and see what this thing &lt;a href=&quot;https://chrisk.io/i/pressmatic&quot;&gt;Pressmatic&lt;/a&gt; was. The developer of Pressmatic was looking for developers to use it out and see if it met their needs for local Development. I was pumped to try something new, but pretty skeptical that it would be right, as most things aren&apos;t perfect. &lt;a href=&quot;https://chrisk.io/i/pressmatic&quot;&gt;Pressmatic&lt;/a&gt; was pretty damn close to perfect. I won&apos;t go into the nitty gritty details as those are on the site, and are pretty boring...but here&apos;s some of the highlights that sold me.&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;Site Defaults&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;With the `New Site Defaults` setting, you can define all of the basic setup information for when you create a site. You have the opportunity to change these upon creation, but it will be pre-filled with this info. saves me so much time when I quickly need a WordPress install.&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;Multisite Support&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;When setting up a new site, you have the option to choose if you want multisite, and not just subdirectory support either!&lt;br /&gt;
&lt;img src=&quot;/images/blog/Screen-Shot-2016-07-02-at-8.08.46-AM.png&quot; alt=&quot;pressmatic-review-multisite-switcher&quot; /&gt;&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;Nginx, Apache, PHP versions, oh my!&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;You have the ability to use (and swap out at any time) either Apache or Nginx as your web server, and you also can choose from 5 versions of PHP (at the time of writing 5.2.4, 5.2.17, 5.3.29, 5.6.20, and 7.0.3).&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;Site templates&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Do you have a base install that you use for every new WordPress development environment? Me too. Anytime I work locally I install a handful of plugins, and with site templates, it&apos;s done for me. Basically how it works is you setup what you want your template to look like, and then you can tell &lt;a href=&quot;https://chrisk.io/i/pressmatic&quot;&gt;Pressmatic&lt;/a&gt; to make it a template. Then when adding a new site, you can choose it as an option and a few minutes later, you&apos;re up and running without having to install any of those utilities. It&apos;s beautiful.&lt;/p&gt;
&lt;p&gt;Don&apos;t want WordPress? That&apos;s fine, I&apos;ve made a non-WordPress template, by basically creating a base WordPress install, deleting all the parts of WordPress, and making a template out of it. Now I just have a quick an easy site that&apos;s ready with PHP and MySQL based off Apache or Nginx.&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;Mailcatcher!!!&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;This is the first time I&apos;ve worked with Mailcatcher, and it&apos;s &lt;em&gt;&lt;strong&gt;amazing&lt;/strong&gt;&lt;/em&gt;. Many times I&apos;ll use email addresses that aren&apos;t valid, in order to test things on my local environments. Things like &lt;code&gt;admin@local.dev&lt;/code&gt; or &lt;code&gt;customer@local.dev&lt;/code&gt;. Obviously these won&apos;t get sent to me, so when I want to test what emails look like when they arrive I have to configure a real email address, which ends up cluttering my inbox. I hate that. Mailcatcher, is basically a local loopback for emails sent via your sites.&lt;br /&gt;
&lt;img src=&quot;/images/blog/Screen-Shot-2016-07-02-at-8.14.26-AM-1024x488.png&quot; alt=&quot;pressmatic-review-mailcatcher&quot; /&gt;&lt;br /&gt;
This essentially gives us an inbox for all the emails that the site sends, in a single window. Beautiful!&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;One-click, Self-Signed Certificate Trusting&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;This is a huge one I didn&apos;t even know I was missing. Being that I develop a lot of code that&apos;s eCommerce based, thanks to Easy Digital Downloads, I tend to always want my local development environments to be over HTTPS with a self-signed certificate. When doing this in MAMP, I&apos;d always be met with the &apos;Do you want to trust this certificate!?!?!?&apos; warning in Chrome and other browsers. Well, &lt;a href=&quot;https://chrisk.io/i/pressmatic&quot;&gt;Pressmatic&lt;/a&gt; made this easy, with a single click.&lt;br /&gt;
&lt;img src=&quot;/images/blog/Screen-Shot-2016-07-02-at-8.15.29-AM.png&quot; alt=&quot;pressmatic-review-trusted-certs&quot; /&gt;&lt;br /&gt;
After &apos;trusting&apos; the cert, I can be fully HTTPS locally without any weird warnings.&lt;/p&gt;
&lt;h4&gt;Other things I like:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Ability to set the default terminal app.&lt;/li&gt;
&lt;li&gt;One click access to SSH and MySQL for any single site&lt;/li&gt;
&lt;li&gt;Add-On management (not many available now, but in the works)&lt;/li&gt;
&lt;li&gt;Automatic Updates to the application&lt;/li&gt;
&lt;li&gt;Quick site duplication&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, overwhelmingly a positive experience. As always there are some things I am either missing aren&apos;t quite what I expect, but that list is pretty small, and a bit picky if you ask me...&lt;/p&gt;
&lt;h4&gt;A few things to improve on:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Does not have the ability to change the path to the web root on an existing site.&lt;/li&gt;
&lt;li&gt;Cannot pick WordPress version at new site creation, some sites I like to run nightly.&lt;/li&gt;
&lt;li&gt;WordPress debug constants are not set on installation (but I hear an add-on is coming for that).&lt;/li&gt;
&lt;li&gt;It&apos;s only OS X (for now)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Those are the only ones I can think of at the moment. Pretty small eh? So far this is the most comprehensive change to my development environment in a while, and it&apos;s pretty much changed it completely. The speed at which I can replicate, create, and destroy sites makes my testing and development much &lt;strong&gt;faster&lt;/strong&gt; and &lt;strong&gt;efficient&lt;/strong&gt;, and &lt;em&gt;&lt;strong&gt;repeatable&lt;/strong&gt;&lt;/em&gt;. Which is key.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;The features of Pressmatic allow me to test and replicate environments much faster.&quot; username=&quot;cklosowski&quot;]&lt;/p&gt;
&lt;h4&gt;The precieved elephant in the room...price&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://chrisk.io/i/pressmatic&quot;&gt;Pressmatic&lt;/a&gt; comes in at $129. &lt;strong&gt;There are no renewals with Pressmatic&lt;/strong&gt;. Licenses are valid for all 1.X releases and you will be able to upgrade at a discount when new major versions are released. This is a pretty standard platform. MAMP has been using it for years with its Pro version.&lt;/p&gt;
&lt;p&gt;One might argue that MAMP Pro is only $59, and you are 100% right. You also get what you pay for. MAMP is running outdated software versions, doesn&apos;t have the template features, and isn&apos;t geared towards WordPress development, which I feel is a huge selling point here. The other major improvement this has over other ones I&apos;ve used is it&apos;s design. It&apos;s just clean, and easy to use as a native OS X app. It&apos;s also not running in such a container platform, which is a huge benefit in my opinion. You have to approach financial decisions about development tools with one thing in mind: &quot;How much time will this save me.&quot; The answer with &lt;a href=&quot;https://chrisk.io/i/pressmatic&quot;&gt;Pressmatic&lt;/a&gt;, is &lt;em&gt;a ton&lt;/em&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Momentarily Pausing the Hustle</title><link>https://chrisk.io/posts/momentarily-pausing-the-hustle/</link><guid isPermaLink="true">https://chrisk.io/posts/momentarily-pausing-the-hustle/</guid><description>Finding a moment to pause the hustle can be good for your emotional and mental state.</description><pubDate>Wed, 29 Jun 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ll admit it, I’m drawn to the “Hustle Movement” that’s gotten widely popular in the entrepreneurship community. The attitudes, the &lt;a href=&quot;https://www.instagram.com/garyvee/&quot;&gt;Instagram accounts&lt;/a&gt;, SnapChat, the Podcasts. All of it. I love that stuff. It’s inspiring, interesting, motivating, and &lt;strong&gt;flat out intoxicating&lt;/strong&gt; to watch people push their businesses to the edge, and succeed. The undisputed heavyweight champion of the hustle in this day and age is &lt;a href=&quot;http://garyvaynerchuk.com&quot;&gt;Gary Vaynerchuk&lt;/a&gt;. No doubt about that. The 24/7 connectedness of our society makes it possible and the remote worker environment, even more so.&lt;/p&gt;
&lt;p&gt;One place I constantly find inspiration is the blog of Jennifer Bourn, named Inspired Imperfection. It’s a great mix of business, family, and healthy living. If you’ve never been there, go and check it out (and be sure to &lt;a href=&quot;https://inspiredimperfection.com/subscribe/&quot;&gt;signup for her newsletter, it’s good stuff&lt;/a&gt;). Jennifer wrote an article a while back named “&lt;a href=&quot;https://inspiredimperfection.com/embrace-grind-grow-business-babies-toddlers/&quot;&gt;Embrace the Grind: Grow a business with babies and toddlers&lt;/a&gt;”. It’s timed perfectly, I have both a baby and a toddler, and well, want to grow business! Awesome.&lt;/p&gt;
&lt;h2&gt;Momentarily pausing the hustle&lt;/h2&gt;
&lt;p&gt;There’s no secret that the hustle can lead to some pretty insane work habits. For better or for worse, you end up working (or thinking about work) more often than your “40 hours”. There’s no shame, it’s what successful people do. Inspiration and business don&apos;t stop when the bell rings at 5pm, because there is no bell. We’re always connected, always consuming, and always thinking of new ways to grow. Taking a little time to yourself in all that hustle, is something I would encourage. I, myself, get a massage every 2 weeks. For my most recent appointment, my regular massage therapist wasn’t available however. At first this really threw me for a loop, thinking it was going to be a ‘going through the motions’ type of day, but something happened, something awesome.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;I had a 60 minute lapse of &apos;hustle&apos;&quot; username=&quot;cklosowski&quot;]&lt;/p&gt;
&lt;h4&gt;Change is good, and helpful&lt;/h4&gt;
&lt;p&gt;My usual massage therapist and I treat my time like a physical therapy session. &lt;a href=&quot;https://www.washingtonpost.com/national/health-science/desk-jobs-can-be-killers-literally/2013/07/15/ce61f9e8-e59b-11e2-aef3-339619eab080_story.html&quot;&gt;Sitting in a chair all day staring at screens is proven to be hard on the body&lt;/a&gt;, and she get’s me all re-aligned and encourages me to stretch and gives me feedback on how my body is doing. It’s awesome, but the session feels more like a workout than relaxation. This is fine, it’s what the goal is. We want to work the muscles back into a state of alignment. This latest visit, not knowing this therapist well, I opted for a little less pressure with a more ‘relaxing’ style. Something told me I needed this anyway, from a emotional and mental perspective.&lt;/p&gt;
&lt;p&gt;Todays’ massage…was mentally stimulating…in all honesty. Instead of my body reacting to the physical act of working out tension, my mind spent more time focusing on, frankly, nothing. I honestly just laid there and tried to be present. It was that way for about 10 or 15 minutes, then flood gates opened. I had a rush of clarity where I wasn’t worried about my work, my family, my kids, my wife. None of it. I had a moment to let my mind stop, and perform. In fact, the outline of this very article was part of the remaining 50 minutes of my session. I had the opportunity to freely think without boundary. It was damn near liberating.&lt;/p&gt;
&lt;h4&gt;Respect yourself while you hustle&lt;/h4&gt;
&lt;p&gt;While I 100% love the hustle mentality, there is something to be said for respecting yourself enough to stop hustling for a moment. Stop pushing so hard to move forward and simply think about where you are. Think about what your state of being is around others. Do you like who you are outside of the hustle?&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;You cannot effectively run a race to which you do not know the end.&quot; username=&quot;cklosowski&quot;]&lt;/p&gt;
&lt;p&gt;Frankly, stop and think about where you are headed, so that you can focus on where you want to go. The massage mentioned above taught me one thing. &lt;em&gt;&lt;strong&gt;Stop&lt;/strong&gt;&lt;/em&gt;. Just for a moment. &lt;em&gt;Stop&lt;/em&gt; the Twitter. &lt;em&gt;Stop&lt;/em&gt; the Instagram. &lt;em&gt;Stop&lt;/em&gt; it all. Think about what is affecting your mood and your relationships. &lt;em&gt;Stop&lt;/em&gt; thinking about what you need to hit your next goal, and start thinking about what is stopping you from being the best version of you, both physically and emotionally.&lt;/p&gt;
&lt;p&gt;Treat yourself today. Focus on tomorrow…tomorrow (but just for today, tomorrow...hustle).&lt;/p&gt;
</content:encoded></item><item><title>Delorean Ipsum generator for WordPress</title><link>https://chrisk.io/posts/delorean-ipsum-generator-for-wordpress/</link><guid isPermaLink="true">https://chrisk.io/posts/delorean-ipsum-generator-for-wordpress/</guid><description>&quot;The way I see it, if you&apos;re gonna build a way to quickly insert placeholder text in your WordPress site, why not do it with some *style?*&quot; A quick plugin…</description><pubDate>Tue, 21 Jun 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you know me even in the slightest, you know I&apos;m a bit of a movie nerd. &lt;a href=&quot;https://chrisk.io/trilogies-order-preference/&quot;&gt;Exhibit A&lt;/a&gt;. Being that the Back to the Future trilogy is one of my favorites, I was pumped to see that &lt;a href=&quot;http://www.polevaultweb.com/&quot;&gt;Iain Poulson&lt;/a&gt; created an awesome little JavaScript tool called Delorean Ipsum, which generates &apos;lorem ipsum&apos; type text, from the script of Back to the Future. Yeah, legit right?!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2016-06-20-at-10.34.22-PM-1024x838.png&quot; alt=&quot;Screen Shot 2016-06-20 at 10.34.22 PM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I&apos;ve been using Delorean Ipsum for a while now, to fill in my development environments when I need to write a page, post, or product content. Why not just use Lorem Ipsum? Well, it&apos;s freeking boring! I love opening up my development environment to see quotes like &quot;Great Scott!&quot; and &quot;There&apos;s that word again, heavy. Why are things so heavy in the future. Is there a problem with the Earth&apos;s gravitational pull?&quot;&lt;/p&gt;
&lt;p&gt;Anyway, I wanted a quicker way to add this content to my WordPress post editor than visiting &lt;a href=&quot;http://deloranipsum.com&quot;&gt;deloranipsum.com&lt;/a&gt; every time I needed it...so I built a little plugin.&lt;/p&gt;
&lt;h4&gt;WordPress Delorean Ipsum Generator&lt;/h4&gt;
&lt;p&gt;This is a pretty simple plugin, &lt;a href=&quot;https://github.com/cklosowski/wp-delorean-ipsum&quot;&gt;available on GitHub&lt;/a&gt; if you want to look it over or suggest changes. Using the button below, you can quickly download a .zip file that you can install on your WordPress site as well. It adds a little &apos;Delorean Ipsum&apos; button to your post edit screen, and provides you with a quick configuration and button to insert the text into the post editor. Nothing fancy, just quick and simple, for when you want a less boring development site.&lt;/p&gt;
&lt;p&gt;[purchase_link id=&quot;2623&quot; style=&quot;button&quot; color=&quot;blue&quot;]&lt;/p&gt;
&lt;h4&gt;Screenshots&lt;/h4&gt;
</content:encoded></item><item><title>Planning for success means planning for failure</title><link>https://chrisk.io/posts/planning-success-means-planning-failure/</link><guid isPermaLink="true">https://chrisk.io/posts/planning-success-means-planning-failure/</guid><description>By planning for failure, your next project should succeed. You may hit a point where things go wrong, but with proper planning, you&apos;ll be prepared for it.</description><pubDate>Tue, 05 Apr 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you ask someone to write out a &apos;game plan&apos; for some arbitrary goal or task they need to achieve, odds are the list will be precisely what needs to happen to achieve the goal. Lists like this are helpful, keep us focused, and 100% on task. So what happens when something doesn&apos;t go as planned. What if step 3 fails...where do you go from there? After all, no one really &apos;plans&apos; to fail. Planning for failure isn&apos;t normal...or is it?&lt;/p&gt;
&lt;h3&gt;Planning for Failure&lt;/h3&gt;
&lt;p&gt;Look, planning for something to go wrong might be &apos;bad joo joo&apos; or &apos;Not thinking positive&apos;, but when time an money are at stake...planning for failure is necessary. In software development, specifically, planning for failure during a release or deployment is called a &apos;Rollback plan&apos;. Today...I used a rollback plan. And it worked out just great in the end.&lt;/p&gt;
&lt;h3&gt;Welcome, Restrict Content Pro&lt;/h3&gt;
&lt;p&gt;The company I work for has a few projects we manage. For the longest time, &lt;a href=&quot;https://chrisk.io/i/rcp&quot;&gt;Restrict Content Pro&lt;/a&gt; (one of our earliest) has been sold as a product on PippinsPlugins.com. Nothing wrong with this, but as we started realizing that we needed a better sales platform for the plugin, we needed to move the sales and marketing to it&apos;s own site, &lt;a href=&quot;https://chrisk.io/i/rcp&quot;&gt;RestrictContentPro.com&lt;/a&gt;. No big deal...except that &lt;a href=&quot;https://chrisk.io/i/pp&quot;&gt;PippinsPlugins.com&lt;/a&gt; has been selling license keys for it for almost 4 years now. This poses quite a challenge when you try and separate 4,000 licenses and payments out of nearly 7,000. Some of which contain the purchase of multiple products.&lt;/p&gt;
&lt;h3&gt;Failure is always an option&lt;/h3&gt;
&lt;p&gt;In a situation like this, moving payments and customers with actively maintained license keys around between sites...one might say &quot;Failure is not an option&quot;. The reality is, failure is always an option. How you plan for that failure though, is where the end result is successful. We knew there was a reasonable chance that at some point during this migration, something could fail. There just wasn&apos;t any illusion that this would be all rainbows and butterflies. So we planned for failure. Prior to running the deployment scripts, we had a list of commands we could run that would set us back to ground zero. A &apos;reset&apos; button if you will, in the form of 6 commands. By having these handy, ready, and proven working, any failure we ran into was easy to stop, take a couple steps back, fix our issues and start again.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;The reality is, failure is always an option.&quot;]&lt;/p&gt;
&lt;p&gt;It&apos;s no secret that situations, where real money is on the line, can cause tense emotions. With a plan on what to do if something fails, no one is left making rash and quick decisions that aren&apos;t well thought out and tested. Quick and untested decisions lead to larger failures, most of the time.&lt;/p&gt;
&lt;h3&gt;Always plan for your failures&lt;/h3&gt;
&lt;p&gt;When planning out a large project with many moving parts, the first thing you should do is pick the points most susceptible to failure, and write a &apos;rollback&apos; or &apos;fallback&apos; plan. Outline the definition of what a failure us, how the item could fail, what it means to the outcome of the project, and any steps you can take to either fix the issue. More importantly than all those, write out the steps needed to get the process back to step one. Essentially, what&apos;s your &quot;reset&quot; button look like?&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;Knowing what to do when something fails ahead of time, leads to success.&quot;]&lt;/p&gt;
&lt;p&gt;With just those things done, you&apos;ll feel much more confident going into your next big release and, while you may experience a failure, you can help the overall project reach a successful outcome.&lt;/p&gt;
</content:encoded></item><item><title>Using Zapier, Twitter, and Pushover to Monitor Your Followers</title><link>https://chrisk.io/posts/using-zapier-twitter-and-pushover-to-monitor-your-followers/</link><guid isPermaLink="true">https://chrisk.io/posts/using-zapier-twitter-and-pushover-to-monitor-your-followers/</guid><description>One of the things that I&apos;ve found the most annoying about all the Twitter apps on my iPhone is that when I get followed by someone new, it takes too many…</description><pubDate>Fri, 11 Mar 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the things that I&apos;ve found the most annoying about all the Twitter apps on my iPhone is that when I get followed by someone new, it takes too many steps to learn a little bit more about them. Typically when someone follows me, I will check their profile, see what they do and if I want to follow back. Usually this takes a couple clicks, swipes, and a few more clicks (especially if I want to follow them from more than one Twitter account).&lt;/p&gt;
&lt;h3&gt;Zaps make things easier&lt;/h3&gt;
&lt;p&gt;Recently I&apos;ve been playing around with an automation service called &lt;a href=&quot;https://zapier.com&quot;&gt;Zapier&lt;/a&gt; (think &apos;zap&apos; like a laser). Zapier is a service that connects all kinds of different web-based services to each other through what they call &apos;Zaps&apos;. These Zaps allow you to make services that would normally not pass data back and forth, do so. There are endless combinations of zaps, but you can get a good idea of the things you can do via their &lt;a href=&quot;https://zapier.com/app/recommendations&quot;&gt;recommended collections&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Using Pushover&lt;/h3&gt;
&lt;p&gt;I love &lt;a href=&quot;https://chrisk.io/pushover&quot;&gt;Pushover&lt;/a&gt;, a mobile app to send any type of data you wish to your phone via a push notification. The strength of Zapier is to take data from one service and send it to another, so in my case, get a little more data than just &lt;code&gt;@username followed you&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;The Zap&lt;/h3&gt;
&lt;p&gt;My Zap looks like this. When I get a new follower on my Twitter account &lt;a href=&quot;https://twitter.com/cklosowski&quot;&gt;@cklosowski&lt;/a&gt;... &lt;img src=&quot;/images/blog/zapier-twitter-new-follower.png&quot; alt=&quot;zapier-twitter-new-follower&quot; /&gt; Trigger a Pushover Notification with the data I&apos;m looking for: &lt;img src=&quot;/images/blog/zapier-pushover-with-twitter.png&quot; alt=&quot;zapier-pushover-with-twitter&quot; /&gt; You&apos;ll even notice I&apos;ve added an &apos;Action URL&apos; that will open my preferred Twitter client on iOS (&lt;a href=&quot;https://chrisk.io/tweetbot&quot;&gt;TweetBot&lt;/a&gt;) to my new follower&apos;s profile so I can quickly follow them from any account I have setup in &lt;a href=&quot;https://chrisk.io/tweetbot&quot;&gt;TweetBot&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I&apos;ve recently also switched back to the official Twitter app for iOS. If you are using that the custom URL to open a profile is &lt;code&gt;twitter://user?screen_name=[screen_name]&lt;/code&gt; using the &apos;Follower Screen Name&apos; ingredient.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;The End Result&lt;/h3&gt;
&lt;p&gt;With this Zap in place (running every 15 minutes), I&apos;ll see the following on my phone when I get a new follower (Hey there &lt;a href=&quot;https://twitter.com/tannermoushey&quot;&gt;@tannermoushey&lt;/a&gt;!). The &lt;strong&gt;&lt;em&gt;Open URL&lt;/em&gt;&lt;/strong&gt; intent and &lt;strong&gt;&lt;em&gt;View Profile&lt;/em&gt;&lt;/strong&gt; link will open up &lt;a href=&quot;https://chrisk.io/tweetbot&quot;&gt;TweetBot&lt;/a&gt; to interact with the profile.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; After using this for a few followers, I noticed that profiles without descriptions caused the Zap to fail. To fix this, you can put a &apos;filter&apos; between the Twitter and Pushover steps that looks to verify that the &apos;Description&apos; exists, and if so, move onto pushing to Pushover.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/IMG_1137-169x300.jpg&quot; alt=&quot;IMG1137&quot; /&gt;&lt;img src=&quot;/images/blog/IMG_1139-169x300.jpg&quot; alt=&quot;IMG1139&quot; /&gt;&lt;img src=&quot;/images/blog/IMG_1140-169x300.jpg&quot; alt=&quot;IMG1140&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Testing IP sensitive data on localhost</title><link>https://chrisk.io/posts/testing-ip-sensitive-data-on-localhost/</link><guid isPermaLink="true">https://chrisk.io/posts/testing-ip-sensitive-data-on-localhost/</guid><description>Recently I&apos;ve been doing some updates to the Fraud Monitor extension for Easy Digital Downloads which helps store owners avoid costly charge-back fees from…</description><pubDate>Mon, 25 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently I&apos;ve been doing some updates to the &lt;a href=&quot;https://chrisk.io/fraud-monitor&quot;&gt;Fraud Monitor extension for Easy Digital Downloads&lt;/a&gt; which helps store owners avoid costly charge-back fees from fraudulent credit card purchases. The most recent feature is one that verifies the IP address that is downloading the files is in a country not on the blacklist.&lt;/p&gt;
&lt;p&gt;When writing this feature I found out that most local hosts (used in development) use either 127.0.0.1 or ::1 as the &apos;IP Address&apos; of the local computer making a request. Even in setups with vagrant and other situations a private IP is what is reveled as the IP making the purchase. The problem is, these IPs are not query-able in tools that do GeoIP lookups, to determine which country, state, or even city an IP address is registered in. This is a key feature of a fraud detection tool. For this reason, I felt it necessary to write a little plugin that does a lookup of my externally facing IP (assigned by my Internet Service Provider) and use IT as my &lt;code&gt;$_SERVER[&apos;REMOTE_ADDR&apos;]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By doing this, now when I make purchase in Easy Digital Downloads (in my local development environment), my IP address will be one that can be run through Geo IP lookups and WHOIS requests, allowing me to develop tools based on these types of services.&lt;/p&gt;
&lt;p&gt;I&apos;ve built a little single file plugin for WordPress to use on your local host during development that checks the external IP once per hour to use it instead of your &apos;local ip&apos;.&lt;/p&gt;
&lt;p&gt;Below, you can download a single file plugin to install on your local WordPress site, allowing you to have the same freedoms to do GeoIP lookups in your WordPress projects.&lt;/p&gt;
&lt;p&gt;[purchase_link id=&quot;2466&quot; text=&quot;Purchase&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;/p&gt;
&lt;p&gt;The code looks like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;?php
/**
* Plugin Name: Public IP FIx
* Plugin URI:  https://chrisk.io
* Description: For testing IP sensitive code, use the public facing IP in your localhost
* Version:     1.0
* Author:      Filament Studios
* Author URI:  https://filament-studios.com
* License:     GPL-2.0+
*/&lt;/p&gt;
&lt;p&gt;/**&lt;br /&gt;
*&lt;br /&gt;
* The point of this plugin is to allow a local development environment to identify&lt;br /&gt;
* the REMOTE_ADDR of the user as the public facing IP, which is able to be used in&lt;br /&gt;
* GeoIP lookups and WHOIS checks for things like fraud services and other types of&lt;br /&gt;
* eCommerce and rate limiting checks&lt;br /&gt;
*&lt;br /&gt;
*/&lt;/p&gt;
&lt;p&gt;if ( ! defined( &apos;ABSPATH&apos; ) ) {&lt;br /&gt;
exit;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;function kfg_use_external_ip() {&lt;/p&gt;
&lt;p&gt;$ip = get_transient( &apos;_kfg_remote_ip&apos; );&lt;/p&gt;
&lt;p&gt;if ( false === $ip ) {&lt;br /&gt;
$response = wp_remote_get( &apos;http://bot.whatismyipaddress.com/&apos; );&lt;/p&gt;
&lt;p&gt;if ( ! is_wp_error( $response ) ) {&lt;br /&gt;
$body = wp_remote_retrieve_body( $response );&lt;br /&gt;
$ip = $body;&lt;br /&gt;
set_transient( &apos;_kfg_remote_ip&apos;, $ip, HOUR_IN_SECONDS );&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;if ( false !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {&lt;br /&gt;
$_SERVER[&apos;REMOTE_ADDR&apos;] = $ip;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;}&lt;br /&gt;
add_action( &apos;plugins_loaded&apos;, &apos;kfg_use_external_ip&apos;, 1 );&lt;/p&gt;
&lt;p&gt;[purchase_link id=&quot;2466&quot; text=&quot;Purchase&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;/p&gt;
</content:encoded></item><item><title>Why #AllMyMovies wasn&apos;t so &quot;stupid&quot;</title><link>https://chrisk.io/posts/why-allmymovies-wasnt-so-stupid/</link><guid isPermaLink="true">https://chrisk.io/posts/why-allmymovies-wasnt-so-stupid/</guid><description>What we can learn, as software developers, from the #AllMyMovies Performance Piece by Shia LaBeouf.</description><pubDate>Thu, 24 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;All the way back in November of 2015, Shia LaBeouf did a performance piece entitled &lt;a href=&quot;http://newhive.com/allmymovies&quot;&gt;#AllMyMovies&lt;/a&gt;. Shia and some friends rented out a theatre in New York City, queued up his entire big screen career in reverse chronological order, and for the next 3 days sat there and watched while a camera was affixed to LaBeouf. No audio was available for the stream, however people were invited to join them in the theater for free at any time.&lt;/p&gt;
&lt;p&gt;Many touted this as one of his more &apos;stupid&apos; antics, in a line of &lt;a href=&quot;https://www.youtube.com/watch?v=ZXsQAXx_ao0&quot;&gt;odd behavior&lt;/a&gt;, me included. Performance art has always been one of those things I&apos;ve never fully grasped, even in my days of art school, but as I kept going back to the live stream to see how weird the concept was...something happened. I caught a glimpse of reflection in his face as he watched a scene from &quot;Surfs Up&quot; (a movie my son loves watching).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/CTkaIlwUcAAxBH5.jpg&quot; alt=&quot;Shia LaBeouf laughing at a scene of Surfs Up! during #AllMyMovies&quot; title=&quot;#AllMyMovies&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Reflection is Good&lt;/h3&gt;
&lt;p&gt;Now, I can&apos;t state exactly what he was reflecting on, or what was in his mind at that exact moment, but putting myself in LaBeouf&apos;s shoes as a creator, I can look back at things I&apos;ve done in the past, and remember interactions with colleagues on the project, discussions, celebrations, or even disappointments. In that one moment, you could see someone&apos;s joy as they remember a moment of their past, by watching their past.&lt;/p&gt;
&lt;p&gt;It helps us remember the good, learn from the bad, honor the forgotten. Reflection is a vew into one&apos;s actions.&lt;/p&gt;
&lt;h3&gt;Reflection as a Developer&lt;/h3&gt;
&lt;p&gt;In the case of #AllMyMovies, it&apos;s pretty easy and entertaining to queue up a bunch of movies and snack on some popcorn while you and your friends hang out for 3 days. As a developer...it&apos;s a little different. All I can picture (in the same medium) is a &quot;Star Wars&quot; style intro scene, with my GitHub commit history scrolling upwards...most would be entirely boring, some profane, others half-assed. I think we&apos;d have to dub it #AllMyCommits&lt;/p&gt;
&lt;p&gt;One thing we can do, however, is periodically go through and refactor our code. Now, some will say that refactoring for the sake of refactoring is just a waste of time, and I would mostly agree with them. If you&apos;re working on a time sensitive environment, the luxury of having time to refactor comes few and far between. When it does happen though, it&apos;s a great moment of reflection on how far you&apos;ve come as a developer, and what you&apos;ve learned since the initial code was written.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;Refactoring your code can become a reflection of your journey as a developer.&quot;]&lt;/p&gt;
&lt;p&gt;Something else you&apos;ll end up noticing though, is the non-code related things happening in your life when you were working on said projects, will start triggering memories. It&apos;s an interesting thing, as a developer, to be looking at code, and remembering &quot;That&apos;s the day I went to that place with that person...good times.&quot; Some might even remind you of less fortunate times, which can help lead to reassurance of where you are now. Development isn&apos;t just about what&apos;s happening now, it&apos;s our form of journaling. It builds a record of our state of mind, at the time it&apos;s written.&lt;/p&gt;
&lt;p&gt;Don&apos;t believe me?&lt;/p&gt;
&lt;h3&gt;How you feel, is usually how you code&lt;/h3&gt;
&lt;p&gt;Ask any high-performing athlete, and they&apos;ll tell you that preparation, routine, and mindset are all very important to their success. The same goes for you as a software developer. If you&apos;re not feeling well, there is stress in your personal life, or your routine is out of whack, you&apos;ll be less productive. Reflecting on your past code can also reflect on your past influences (good and bad).&lt;/p&gt;
&lt;p&gt;Some people have the ability to completely isolate their external stresses and not let it affect their code. It&apos;s not easy to do and typically consists of routines. Setting the environment, certain type of music, temperature, etc. Find your ideal environment, and consistently re-create it, and you&apos;ll see a boost in your productivity and quality. One that, as you reflect, you&apos;ll notice.&lt;/p&gt;
&lt;h3&gt;My challenge to you: #SomeOfMyCommits&lt;/h3&gt;
&lt;p&gt;I know that challenging you to review #AllMyCommits would be near impossible, and take days or even weeks in some of your cases. So, I want to challenge you to review one single project. Go through something you remember writing more than 6 months ago. Look it over, dissect it, and see if you can do it better. See if it brings up any memories of life at that time. I&apos;ve got a few pretty vivid ones.&lt;/p&gt;
&lt;p&gt;As I am working on the upcoming Post Promoter Pro 2.3 release, I&apos;m refactoring some code that was written back on the initial release. A release that I finalized when I was vacationing with my family and parents and brother, down in the Tucson area. My son ended up being sick with what we later found out was an ear infection. My brother and I went to a Friday Night Magic event at my local game shop. There are a ton of other details that I&apos;ll spare you of, but I think you get the point.&lt;/p&gt;
&lt;p&gt;Reflection is good, and you should do it from time to time.&lt;/p&gt;
</content:encoded></item><item><title>Proficiency is a Bubble</title><link>https://chrisk.io/posts/proficiency-is-a-bubble/</link><guid isPermaLink="true">https://chrisk.io/posts/proficiency-is-a-bubble/</guid><description>Before I even get going, I want you to tell me 3 things you would deem yourself proficient at. Got 3? Great. Now: I want you to think of 2 people in one of…</description><pubDate>Sat, 14 Nov 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Before I even get going, I want you to tell me 3 things you would deem yourself &lt;em&gt;proficient&lt;/em&gt; at.&lt;/p&gt;
&lt;p&gt;Got 3? Great. Now:&lt;/p&gt;
&lt;p&gt;I want you to think of 2 people in one of those fields, that are more proficient than you are. Can you think of 2? If you can&apos;t, it&apos;s time to expand your bubble.&lt;/p&gt;
&lt;h3&gt;Proficiency is a Bubble&lt;/h3&gt;
&lt;p&gt;If you are going to get anywhere in your career, you need to pop your &apos;Proficiency Bubble&apos;, and do it quickly. Why?&lt;/p&gt;
&lt;p&gt;The only way you can perceive that you are proficient at something is if you feel you are better, or as good as, other people around you, who do the same thing. When we perceive that we are at the top of a skill set, we tend, as humans do, to stop pursuing further accomplishments and maintain. If you surround yourself with people who are better at things than you are, you&apos;ve essentially bursted that &apos;bubble&apos; of proficiency that was surrounding you when you didn&apos;t know better.&lt;/p&gt;
&lt;h3&gt;Knowing when it&apos;s time to expand&lt;/h3&gt;
&lt;p&gt;In our day to day work, it&apos;s extremely easy to lose sight of where we stand within our respective realms. We&apos;re so focused on tasks, that we forget we need t see where this ship is headed, sometimes. If at any point, you stop working for a moment to see what&apos;s new in your area of focus, and can&apos;t think of who you should be looking to for guidance; One of two things has happened:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You ARE the person people are looking to for guidance (in which case, it&apos;s time to find a new person to focus on)&lt;/li&gt;
&lt;li&gt;You need to expand your horizons, and meet/follow/befriend some new people in your field.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Your bubble should be expanding&lt;/h3&gt;
&lt;p&gt;As you move through your career and learn new skills and areas of proficiency, you can quickly find yourself isolated.&lt;/p&gt;
&lt;p&gt;Back when I was at GoDaddy, I was moved from a team focused primarily on PHP and WordPress, to NodeJS and using Handlebars for markup. I&apos;d never used either of these stacks before, so this was new. The first thing I did though? I went and found the people who were leading the way in NodeJS and Handlebars and followed them on Twitter. I found some developers blogging about the topics and bookmarked them. If someone gave a good response on StackOverflow, I looked up their social profiles to see if they always talked about this kind of stuff.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;As your skills expand, you need to expand your social &apos;bubble&apos;.&quot;]&lt;/p&gt;
&lt;h3&gt;Stay Connected&lt;/h3&gt;
&lt;p&gt;About once a month I like to do 2 things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go through some influential developers in my bubble, and see who they are following, replying to, and mentioning on Twitter. Odds are I&apos;ll find a new one I should be following.&lt;/li&gt;
&lt;li&gt;Scroll through some key hashtags on Twitter, and see what&apos;s happening in the space. These hashtags will change depending on your sphere, but the principal remains the same.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I know these are Twitter related, but that&apos;s where the bulk of my developer and product towner communities live.&lt;/p&gt;
&lt;p&gt;The other great thing to do is meetups. Yep, actual, physical, face-to-face meetups. I can&apos;t tell you how much I get out of showing up to my local WordPress meetups. They inspire and motivate me, which is why I try and attend 2 a month.&lt;/p&gt;
</content:encoded></item><item><title>Hide categories with no visible products in the Product Category Widget</title><link>https://chrisk.io/posts/woocommerce-hide-categories-with-no-visible-products-in-the-product-category-widget/</link><guid isPermaLink="true">https://chrisk.io/posts/woocommerce-hide-categories-with-no-visible-products-in-the-product-category-widget/</guid><description>By default, the WordPress wp_list_categories function will...get a list of categories. Surprising, I know. It will also even exclude empty categories if you…</description><pubDate>Sat, 07 Nov 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;By default, the WordPress wp_list_categories function will...get a list of categories. Surprising, I know. It will also even exclude empty categories if you want, meaning if a category has no items belonging to it, it will not display it.&lt;/p&gt;
&lt;p&gt;It&apos;s awesome, I really dig this function. The Woocommerce Product Categories Widget uses it to display a list of categories for your Woocommerce products. It will even hide categories that do not have any products in them, much like the the default behavior for post categories, etc.&lt;/p&gt;
&lt;p&gt;Where it doesn&apos;t always work though, is when the product is published, but isn&apos;t visible, due to stock or backorder status...so here&apos;s a quick function that will look at the categories in the product list, find the products in the category, and if none of the products are visible, it will not display the category in the widget:&lt;br /&gt;
[purchase_link id=&quot;3187&quot; text=&quot;Get Plugin File&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;br /&gt;
https://gist.github.com/cklosowski/df41c06eb21f0405a618606f2b0daacc&lt;br /&gt;
[purchase_link id=&quot;3187&quot; text=&quot;Get Plugin File&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;/p&gt;
</content:encoded></item><item><title>Code Snippet: Clean up your Local Development Admin Bar</title><link>https://chrisk.io/posts/code-snippet-clean-up-your-local-development-admin-bar/</link><guid isPermaLink="true">https://chrisk.io/posts/code-snippet-clean-up-your-local-development-admin-bar/</guid><description>As a developer of WordPress plugins, it&apos;s safe to say that my Admin bar is FULL of super useful items added by plugins that help me develop more…</description><pubDate>Tue, 27 Oct 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a developer of WordPress plugins, it&apos;s safe to say that my Admin bar is FULL of super useful items added by plugins that help me develop more efficiently. That being said, it&apos;s also full of a bunch of &apos;junk&apos; that just isn&apos;t needed in my local environment most of the time. Case in point, the &apos;Updates&apos; icon and the &apos;Comments&apos; icon.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Screen-Shot-2015-10-27-at-10.16.02-AM.png&quot;&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2015-10-27-at-10.16.02-AM.png&quot; alt=&quot;Screen Shot 2015-10-27 at 10.16.02 AM&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In addition to all the default items that show up in a Network Install I&apos;ve got items added by &lt;a href=&quot;https://wordpress.org/plugins/query-monitor/&quot;&gt;Query Monitor&lt;/a&gt;, &lt;a href=&quot;https://github.com/norcross/airplane-mode&quot;&gt;Airplane Mode&lt;/a&gt;, &lt;a href=&quot;https://wordpress.org/plugins/debug-bar/&quot;&gt;Debug Bar&lt;/a&gt;, &lt;a href=&quot;https://wordpress.org/plugins/plugin-toggle/&quot;&gt;Plugin Toggle&lt;/a&gt;, and &lt;a href=&quot;https://chrisk.io/2015/02/code-snippet-show-blog-id-admin-header/&quot;&gt;my own Blog ID item&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My main machine is a Macbook Air 11&quot; and from time to time, I disconnect from the monitors and work on the single screen, and with that many items, it get&apos;s a little crowded. So here&apos;s what I&apos;ve dropped into my own MU plugin to help clean up the interface a bit:&lt;/p&gt;
&lt;p&gt;&amp;lt;?php
function kfg_remove_admin_bar_items( $wp_admin_bar ) {
$wp_admin_bar-&amp;gt;remove_node( &apos;wp-logo&apos; );
$wp_admin_bar-&amp;gt;remove_node( &apos;updates&apos; );
$wp_admin_bar-&amp;gt;remove_node( &apos;comments&apos; );
}
add_action( &apos;admin_bar_menu&apos;, &apos;kfg_remove_admin_bar_items&apos;, PHP_INT_MAX, 1 );&lt;/p&gt;
&lt;p&gt;With this, I get the following view:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Screen-Shot-2015-10-27-at-10.20.53-AM.png&quot;&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2015-10-27-at-10.20.53-AM.png&quot; alt=&quot;Screen Shot 2015-10-27 at 10.20.53 AM&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This both cleans up some of the unnecessary items. The reason for getting rid of the &apos;updates&apos; notifications is I work mostly off Git branches, which sometimes I&apos;m installing a version that isn&apos;t latest on the WordPress.org repository for testing purposes.&lt;/p&gt;
&lt;p&gt;Anyway, I hope that helps some devs out in getting rid of items they don&apos;t want to see in their development environment. You can &lt;a href=&quot;https://codex.wordpress.org/Function_Reference/remove_node&quot;&gt;read more about the `remove_node` method on the WordPress Codex&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cheers.&lt;/p&gt;
</content:encoded></item><item><title>Hindsight is 20/20</title><link>https://chrisk.io/posts/hindsight-is-2020/</link><guid isPermaLink="true">https://chrisk.io/posts/hindsight-is-2020/</guid><description>When I was in 5th grade, I loved gym class. Who wouldn&apos;t. Dodgeball, red rover, popcorn, and scooters . It was what most energy filled elementary school…</description><pubDate>Fri, 04 Sep 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I was in 5th grade, I loved gym class. Who wouldn&apos;t. Dodgeball, red rover, popcorn, and &lt;em&gt;scooters&lt;/em&gt;. It was what most energy filled elementary school students looked forward to. For me, it was all about the scooters. Coasting across a laminate gymnasium floor on 1 square foot of molded plastic and 360° spinning wheels. They looked a bit like this.&lt;br /&gt;
&lt;img src=&quot;http://ecx.images-amazon.com/images/I/31mrE1Xy0OL.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There were some rules, obviously. The school didn&apos;t want a bunch of damaged kids at the end of the day. Most were totally reasonable. No standing, no bumping, no laying down on your stomach. The normal stuff.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Wait, no laying down on your stomach?!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To me that was &lt;em&gt;stupid&lt;/em&gt;. How can laying down hurt you. Simple, one small spec of debris...and bam...your chin hits the ground and splits wide open, requiring stitches and leaving a scar on your chin for life.&lt;/p&gt;
&lt;p&gt;You can probably guess how I would come to this conclusion. I didn&apos;t heed the warnings.&lt;/p&gt;
&lt;p&gt;Looking back, I probably wouldn&apos;t have laid down on that scooter, had I known it would lead to getting stitches (I hate needles) and I&apos;d be scarred for life.&lt;/p&gt;
&lt;h3&gt;Sharing is caring&lt;/h3&gt;
&lt;p&gt;Much, much more recently, I was reading &lt;a href=&quot;https://chrisk.io/Linchpin&quot;&gt;Linchpin by Seth Godin&lt;/a&gt; and it made me think back to some of my first weeks as a developer. While I scratched my unshaven (and scarred) chin, memories of really embarrassing moments, frustrating conversations, and triumphant victories had me somewhat yearning for the times when you are soaking up knowledge at such an incredible rate. Then the flashbacks of bugs past started creeping in, and with that...the inevitable &apos;famous last words&apos; I spoke prior to testing and/or deployment.&lt;/p&gt;
&lt;p&gt;&quot;Why do I need that much redundancy?&quot;, &quot;No, the value will always be within this range.&quot;, &quot;That service is always reachable&quot;, and my personal favorite &quot;It worked in test?! Quick roll it back!&quot;&lt;/p&gt;
&lt;p&gt;Well, now that my blood pressure has risen a little just from recalling these moments, there are a few key concepts I think that really stood out to me as &apos;career maker&apos; moments that got me through to where I am.&lt;/p&gt;
&lt;h4&gt;Start by learning the concepts&lt;/h4&gt;
&lt;p&gt;When I started my first professional software development job...I was told by my Sr. Developer that I should convert my work in progress to a singleton. I said sure...then hit Google. What the &lt;em&gt;hell&lt;/em&gt; is a &apos;singleton&apos;. From there, I realized there was terminology and practices that were not tied to any one specific language, so I better start brushing up on the overall concepts of software development. Concepts, that translate into whichever language you end up writing.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;Becoming a &apos;professional software developer&apos; means becoming a student of the craft.&quot;]&lt;/p&gt;
&lt;p&gt;When it comes to conceptually improving your development skills, I always recommend &lt;a href=&quot;https://chrisk.io/CleanCode&quot;&gt;Clean Code by Robert C. Martin&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;&quot;Maybe&quot; is an acceptable answer, with follow through&lt;/h4&gt;
&lt;p&gt;This one is more tied to people who work for clients or development managers, but at some point, we&apos;re all asked &quot;Is X possible?&quot;. My initial reaction (based on all of 3 seconds of time to think about it) was usually &quot;No&quot;. I&apos;d go back to my desk, think about it, then have a solution an hour later. Saying &apos;maybe&apos; is perfectly fine, as long as you follow through with the findings.&lt;/p&gt;
&lt;h4&gt;You are going to be wrong, a lot. Learn to live with that&lt;/h4&gt;
&lt;p&gt;Nobody is perfect. Developers, doubly so. We make mistakes, and we make them a lot. Most of the time nobody sees them but us. Think about your last bit of code you wrote. How many tiny iterations of the logic did you go through? Did you mix up a &apos;haystack/needle&apos; ordering? From time to time, these bugs make their way into the view of another developer (or heaven forbid, a user). It happens. We&apos;re human. The best course of action is to fix it, learn &apos;why&apos; it got past you, and find ways to prevent it in the future.&lt;/p&gt;
&lt;p&gt;I saw a quote somewhere the other day that summed this point up in two sentences:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Software development is 90% debugging. The other 10% is writing bugs.&lt;/p&gt;
&lt;p&gt;– Someone telling the truth&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Need I say more?&lt;/p&gt;
&lt;p&gt;To be completely honest, I&apos;ve only got about 5 years of professional development under my belt. In those 5 years, I&apos;ve had the opportunity to learn from some of the most intelligent people I&apos;ve ever met. Some of the lessons I learned were of my own accord, and some passed down from my mentors. I reached out to some other developers I know, asking what they would have told themselves, when they were first starting out as developers.&lt;/p&gt;
&lt;h4&gt;What I would tell &apos;beginner me&apos;&lt;/h4&gt;
&lt;h4&gt;...about learning&lt;/h4&gt;
&lt;p&gt;https://twitter.com/jchristopher/status/639456349827547137&lt;br /&gt;
https://twitter.com/jpetersen/status/639456357796716544&lt;br /&gt;
https://twitter.com/NaveenS16/status/639481064705003520&lt;/p&gt;
&lt;h4&gt;...on mentors&lt;/h4&gt;
&lt;p&gt;https://twitter.com/JiveDig/status/639493429068697605&lt;br /&gt;
https://twitter.com/kikodoran/status/639489356898635776&lt;/p&gt;
&lt;h4&gt;...on consistent improvement&lt;/h4&gt;
&lt;p&gt;https://twitter.com/MrKyleMaurer/status/639493789480935424&lt;br /&gt;
https://twitter.com/ChrisWiegman/status/639487176431026176&lt;br /&gt;
https://twitter.com/SDavisMedia/status/639462193650515968&lt;/p&gt;
&lt;h4&gt;...on becoming, a dentist?&lt;/h4&gt;
&lt;p&gt;https://twitter.com/badmanatee/status/639458618203467780&lt;/p&gt;
&lt;h4&gt;...on balance&lt;/h4&gt;
&lt;p&gt;https://twitter.com/brianbourn/status/639489972991488000&lt;/p&gt;
&lt;h4&gt;What&apos;s one thing you would have told &apos;beginner you&apos; when you started out in your career (development or not).&lt;/h4&gt;
</content:encoded></item><item><title>How Writing One Plugin Changed My Lifestyle</title><link>https://chrisk.io/posts/how-writing-one-plugin-changed-my-lifestyle/</link><guid isPermaLink="true">https://chrisk.io/posts/how-writing-one-plugin-changed-my-lifestyle/</guid><description>Outside of the development world, it&apos;s difficult to describe how I landed on my current &apos;remote worker lifestyle&apos;. The concept of working from home isn&apos;t…</description><pubDate>Wed, 02 Sep 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Outside of the development world, it&apos;s difficult to describe how I landed on my current &apos;remote worker lifestyle&apos;. The concept of working from home isn&apos;t new to most people. Some think it&apos;s a late night infomercial&apos;s pipe-dream, and some 100% understand it. When I tell them, though, that I work when I need to, where I need to, and how I need to, without &lt;em&gt;&quot;being my own boss&quot;&lt;/em&gt;, they get curious. Where I lose them though, is that it all started with open source.&lt;/p&gt;
&lt;p&gt;To be fair, this occurs mostly due to the fact that I then have to explain open source and the philosophy of giving back to a community via code (or &quot;Working for Free&quot; in their minds), but once we get past that, it&apos;s kind of an inspiring discussion that actually excites me.&lt;/p&gt;
&lt;h3&gt;Just a little push&lt;/h3&gt;
&lt;p&gt;Back in 2012, a service called Pushover was released that allowed an API to talk to a mobile Application, basically giving you the platform to send push notifications with just about any data you wanted, to your mobile device. I was digging this. It was pre-WordPress push notifications for mobile apps and I hate email. I built Pushover Notifications for WordPress (not my first plugin but, my first big one) to allow things like comments and password reset warnings to be sent to your mobile device instead of clogging up your inbox. Then Adam Pickering of Astoundify sent me a tweet:&lt;/p&gt;
&lt;p&gt;https://twitter.com/adampickering_/status/241666738163433472&lt;/p&gt;
&lt;p&gt;From here, it was just me learning the EDD ecosystem, and then discussing the details of a hosted extension with Pippin. Things stayed pretty &quot;status quo&quot; until the first &lt;a href=&quot;http://pressnomics.com/&quot;&gt;Pressnomics&lt;/a&gt; event took place in Chandler, AZ.&lt;/p&gt;
&lt;h3&gt;Face to Face&lt;/h3&gt;
&lt;p&gt;I didn&apos;t actually attend Pressnomics 1. At the time I was a software developer at GoDaddy, and the business of WordPress wasn&apos;t something that my job considered part of my scope, and it wasn&apos;t something I could afford on my own dollar. However, Pippin was attending, and I was only a 40 minute drive away, so we met up for beers and talked WordPress, life, development and what not. Great times, but more importantly (unaware at the time), laying the foundation for what my future was to become.&lt;/p&gt;
&lt;h3&gt;Contributing&lt;/h3&gt;
&lt;p&gt;After about 6 months of using EDD as an end user to sell WordPress plugins with the Software Licensing extension, I found something that I could improve. On February 3rd of 2013, this magic happened:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/easydigitaldownloads/Easy-Digital-Downloads/commit/ea864646866ce0a7f5969835d89a98e804ecbb54&quot;&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2015-06-11-at-4.15.40-PM.png&quot; alt=&quot;Screen Shot 2015-06-11 at 4.15.40 PM&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My first ever commit to EDD core. I went on to make 11 more commits that year. Super minor in the scheme of things, but super important to where I am today.&lt;/p&gt;
&lt;h3&gt;Supporting the Users&lt;/h3&gt;
&lt;p&gt;In 2014 I started as a contractor, doing support and eventually development for EDD. This was in addition to my full-time job as a Software Developer at GoDaddy, and at times, really put a strain on my home life, as I was working after work was done.&lt;/p&gt;
&lt;h3&gt;Taking the Leap&lt;/h3&gt;
&lt;p&gt;Throughout my career at GoDaddy, I had worked on a large number of projects that ranged from writing my familiar PHP and WordPress, Classic ASP, .Net, and eventually NodeJS. This really made me confident in my skills and made me feel more comfortable with a decision I had been pondering for almost 8 months, but could never seem to do. I announced my 2 week notice at GoDaddy and accepted a position as a full time employee working on Easy Digital Downloads.&lt;/p&gt;
&lt;p&gt;Leaving stable corporate life is a nerve-wrecking and odd feeling, but for me, it was about lifestyle. With a 2 year old son, and another child due in August (born August 10th to be exact), being home to help my wife and see my kids more often was the key. The move also allowed me to take trips with the family and work when I was able to, where I was able to. The freedom to choose the work hours and venues is so key to my new lifestyle.&lt;/p&gt;
&lt;h3&gt;My new challenges&lt;/h3&gt;
&lt;p&gt;With all that awesomeness described above, the real problem now becomes, managing that ever-so-important work/life balance. As many of you know, in software development, there is always the chance you&apos;ll have to work a long day, a weekend, or even an emergency in the middle of the night when needed.&lt;/p&gt;
&lt;p&gt;This is just assumed, but when you work from home, on a flexible schedule...that goes out the door and it becomes very easy to just work whenever you sit down for 30 seconds. This is my new challenge.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;Work/life balance isn&apos;t a buzz topic. It&apos;s real and affects everyone you interact with.&quot;]&lt;/p&gt;
&lt;p&gt;Thankfully I have a &lt;em&gt;&lt;strong&gt;wonderful&lt;/strong&gt;&lt;/em&gt; wife who understands that I have the luxury of working in my field of passion, writing code. With that passion comes the inane &apos;a_bility&apos;_ to always be thinking about it, even when I&apos;m not sitting at my computer. This has lead to a few couch-coding sessions while relaxing with the family, and some late dinners, which ultimately lead up to some stress.&lt;/p&gt;
&lt;p&gt;My truest challenge in this new lifestyle is knowing when it&apos;s time to ignore Slack, shut off email, take off the Pebble, and just spend time with my family. It&apos;s a challenge I&apos;m learning to face, and the hardest part is admitting to myself that it&apos;s a problem. It&apos;s come up in conversation a couple times with my wife, and every time, she lets me know when I&apos;m failing. Honesty here is the key. Not guilt, not anger, just brutal honesty of when I&apos;m not being the best husband and dad because I&apos;m putting work before them.&lt;/p&gt;
&lt;p&gt;I think one great thing we did as a team, not to long ago, was to sit down and have an open discussion on expectations and work habits. We&apos;ve all agreed that we need to tackle the balance and even when our passion get&apos;s the best of us, learn when to turn it off and tend to our &apos;non-work&apos; life. Getting those concerns and opinions out in the open air was very important. It&apos;s helping with the &apos;Did I work enough this week?&apos; internal monologue, and really allowing me to be confident in the fact that I&apos;m giving what&apos;s expected of me.&lt;/p&gt;
&lt;p&gt;[bctt tweet=&quot;Work/Life balance cannot be overcome on your own. It takes accountability and openness.&quot;]&lt;/p&gt;
&lt;p&gt;I&apos;m blessed to have the opportunity to work for Pippin and have someone who understands the importance of family at the heart of my daily work life. I&apos;m also blessed to have the support of my wife to do what I love to do, even if that means an odd and sometimes changing work schedule.&lt;/p&gt;
&lt;h4&gt;What are some of your work/life balance techniques? Do you have set schedule imposed on yourself? Please share something you are doing to make sure you are taking care of your life outside of work.&lt;/h4&gt;
&lt;p&gt;Featured image (&lt;a href=&quot;http://twolovesphotography.com/&quot;&gt;Family Portrait taken by Two Loves Photography in Arizona&lt;/a&gt;)&lt;/p&gt;
</content:encoded></item><item><title>WordPress Silence is Golden snippet for Sublime Text 2/3</title><link>https://chrisk.io/posts/wordpress-silence-is-golden-snippet-for-sublime-text-2-3/</link><guid isPermaLink="true">https://chrisk.io/posts/wordpress-silence-is-golden-snippet-for-sublime-text-2-3/</guid><description>When I&apos;m writing plugins for WordPress, there are a lot of &apos;models&apos; I follow to help speed up the process and one of my favorites is using snippets in…</description><pubDate>Wed, 22 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I&apos;m writing plugins for WordPress, there are a lot of &apos;models&apos; I follow to help speed up the process and one of my favorites is using snippets in Sublime Text. In WordPress, when building plugins, it&apos;s common to use the following code at the beginning of PHP files you do not want to be accessed directly:&lt;/p&gt;
&lt;p&gt;&amp;lt;?php
if ( ! defined( &apos;ABSPATH&apos; ) ) {
exit;
}&lt;/p&gt;
&lt;p&gt;Some people add a comment like &lt;code&gt;// Silence is golden&lt;/code&gt; to this to be witty.&lt;/p&gt;
&lt;h4&gt;What does this do?&lt;/h4&gt;
&lt;p&gt;Well, since PHP files can be directly accessed from the web browser, anything you don&apos;t want to be loaded individually (without the rest of your plugin) needs a way to prevent this. What this does is looks for the constant &lt;code&gt;ABSPATH&lt;/code&gt;, which is defined during the WordPress load process. The &lt;code&gt;wp-load.php&lt;/code&gt; file to be specific. This means that unless WordPress has loaded, our file cannot be accessed directly from the browser.&lt;/p&gt;
&lt;h4&gt;I&apos;m kind of forgetful&lt;/h4&gt;
&lt;p&gt;Well, I often forget to add this to the beginning of new files added to my projects for the sheer fact that I&apos;m in the mindset of getting something written down quickly...so, I&apos;ve turned it into a snippet to make it easy and quick to add it, without losing a thought. The following is a Sublime Text Snippet that you can save it as &lt;code&gt;Packages/User/silence-is-golden.sublime-snippet&lt;/code&gt; in the location that Sublime Text stores packages, that then lets you simply start typing &lt;code&gt;silence&lt;/code&gt;, and hit &lt;code&gt;enter&lt;/code&gt; to enter this quick if statement.&lt;/p&gt;
&lt;p&gt;&amp;lt;snippet&amp;gt;
&amp;lt;content&amp;gt;&amp;lt;![CDATA[
if ( ! defined( &apos;ABSPATH&apos; ) ) {
exit;
}
]]&amp;gt;&amp;lt;/content&amp;gt;
&amp;lt;tabTrigger&amp;gt;silence&amp;lt;/tabTrigger&amp;gt;
&amp;lt;scope&amp;gt;source.php&amp;lt;/scope&amp;gt;
&amp;lt;/snippet&amp;gt;&lt;/p&gt;
&lt;p&gt;[purchase_link id=&quot;2449&quot; text=&quot;Purchase&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;/p&gt;
&lt;p&gt;The workflow looks something like this: &lt;img src=&quot;/images/blog/Screen-Shot-2015-07-22-at-2.13.24-PM.png&quot; alt=&quot;Screen Shot 2015-07-22 at 2.13.24 PM&quot; /&gt; &lt;strong&gt;Hit &apos;Enter&apos;&lt;/strong&gt; &lt;img src=&quot;/images/blog/Screen-Shot-2015-07-22-at-2.14.47-PM.png&quot; alt=&quot;Screen Shot 2015-07-22 at 2.14.47 PM&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>WooCommerce - Hide out of stock products, only when backorders aren&apos;t allowed</title><link>https://chrisk.io/posts/woocommerce-hide-out-of-stock-products-only-when-backorders-arent-allowed/</link><guid isPermaLink="true">https://chrisk.io/posts/woocommerce-hide-out-of-stock-products-only-when-backorders-arent-allowed/</guid><description>A while back I wrote about how I was using WooCommerce for a site my Wife was running. It&apos;s been running totally solid since then, with very minimal…</description><pubDate>Wed, 17 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A while back I wrote about &lt;a href=&quot;https://chrisk.io/2014/11/not-everything-nail/&quot;&gt;how I was using WooCommerce&lt;/a&gt; for a site my Wife was running. It&apos;s been running totally solid since then, with very minimal involvement from my part, which was my goal. Recently she asked a couple questions about how to achieve some things and I couldn&apos;t find a way. They were:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Charge a fee based off the category a product belonged to&lt;/li&gt;
&lt;li&gt;Only show items out of stock that were accepting backorders&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first, I turned into a plugin, available for purchase: &lt;a href=&quot;https://filament-studios.com/downloads/woocommerce-category-fees/&quot;&gt;WooCommerce - Category Fees plugin&lt;/a&gt;. The second, was a custom function that I wrote.&lt;/p&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;WooCommerce as a plugin to &apos;Hide out of stock items&apos;, the problem is that it also hides out of stock items that are accepting backorders. We wanted to hide out of stock items, unless they accepted backorders.&lt;/p&gt;
&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;So heres my quick fix. First, leave the box to &apos;Hide out of stock items from the catalog&apos; &lt;em&gt;&lt;strong&gt;unchecked&lt;/strong&gt;&lt;/em&gt;. Then paste this into the appropriate plugin or theme file:&lt;/p&gt;
&lt;p&gt;function kfg_show_backorders( $is_visible, $id ) {
$product = new wC_Product( $id );&lt;/p&gt;
&lt;p&gt;if ( ! $product-&amp;gt;is_in_stock() &amp;amp;&amp;amp; ! $product-&amp;gt;backorders_allowed() ) {&lt;br /&gt;
$is_visible = false;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;return $is_visible;&lt;br /&gt;
}&lt;br /&gt;
add_filter( &apos;woocommerce_product_is_visible&apos;, &apos;kfg_show_backorders&apos;, 10, 2 );&lt;/p&gt;
&lt;p&gt;[purchase_link id=&quot;2457&quot; text=&quot;Purchase&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;/p&gt;
&lt;p&gt;Now, items that are out of stock that &lt;em&gt;accept&lt;/em&gt; backorders will be visible, while out of stock items that &lt;em&gt;do not&lt;/em&gt; accept backorders will be hidden.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Commenter Oliver found out how to make variation products gray out variations that are sold out, yet keep other variations selectable in &lt;a href=&quot;https://chrisk.io/woocommerce-hide-out-of-stock-products-only-when-backorders-arent-allowed/#comment-3564&quot;&gt;this comment below&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>How We Updated 37 Plugins in 4 Days</title><link>https://chrisk.io/posts/how-we-updated-37-plugins-in-4-days/</link><guid isPermaLink="true">https://chrisk.io/posts/how-we-updated-37-plugins-in-4-days/</guid><description>If you haven&apos;t heard by now, there was a massive day of security releases for several WordPress plugins , and Easy Digital Downloads was no different . We…</description><pubDate>Thu, 23 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you haven&apos;t heard by now, there was a &lt;a href=&quot;https://make.wordpress.org/plugins/2015/04/20/fixing-add_query_arg-and-remove_query_arg-usage/&quot;&gt;massive day of security releases for several WordPress plugins&lt;/a&gt;, and &lt;a href=&quot;https://easydigitaldownloads.com/blog/security-fix-released/?ref=371&quot;&gt;Easy Digital Downloads was no different&lt;/a&gt;. We were included in a batch of auto updates to correct an issue with the way we were using the &lt;code&gt;add_query_arg()&lt;/code&gt; and &lt;code&gt;remove_query_arg()&lt;/code&gt; functions. Unlike many other plugin authors, we have a large number of extensions that we manage and push releases for ourselves, not via WordPress.org. So how did we push 6 versions of Easy Digital Downloads, and also update 37 extensions all in the timeframe? It was a collection of command line scripts and process that helped us nail this down so quickly and accurately. So here&apos;s how we did it.&lt;/p&gt;
&lt;h3&gt;Identify all the _query_args&lt;/h3&gt;
&lt;p&gt;In total, the &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads&lt;/a&gt; Team manages 120 repositories on GitHub. They all needed to be checked to make sure they didn&apos;t contain this bug. First step, checking out 120 GitHub Repositories. With that our first little tip. &lt;strong&gt;Getting all of our repositories in 1 command&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;curl -u [[USERNAME]] -s https://api.github.com/orgs/[[ORGANIZATION]]/repos?per_page=200 | ruby -rubygems -e &apos;require &quot;json&quot;; JSON.load(STDIN.read).each { |repo| %x[git clone #{repo[&quot;ssh_url&quot;]} ]}&apos;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/caniszczyk/3856584#comment-1298718&quot;&gt;source&lt;/a&gt; With this, replace &lt;code&gt;[[USERNAME]]&lt;/code&gt; with your GitHub username, &lt;code&gt;[[ORGANIZATION]]&lt;/code&gt; with the organization you want all the repos of, and you&apos;ll end up with all of them in the current directory. From there, we needed to find all references to the two functions &lt;code&gt;add_query_arg()&lt;/code&gt; and &lt;code&gt;remove_query_arg()&lt;/code&gt;. For this I used a command called &lt;code&gt;ack&lt;/code&gt; &lt;strong&gt;Find all the references&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ack &quot;_query_arg/(&quot;&lt;/p&gt;
&lt;p&gt;This gave me a list of files, and their lines of where we referenced these functions. It was basically a list of 187 lines across 37 extensions. A single line looked something like this:&lt;/p&gt;
&lt;p&gt;-edd-amazon-s3/edd_s3.php:177: $form_action_url = add_query_arg( array( &apos;edd_action&apos; =&amp;gt; &apos;s3_upload&apos; ), admin_url() );&lt;/p&gt;
&lt;h3&gt;Separate the Work&lt;/h3&gt;
&lt;p&gt;Nothing super special here, Pippin and I used Google Spreadsheets to make a matrix of Extensions and EDD Core versions that needed updates. Each had a column of Patched, Tested, and Deployed. This way we could easily track and make sure nothing fell through the cracks.&lt;/p&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;For the extensions, it was a bulk of manual testing. For Core however, we have PHPUnit setup for unit testing. We needed a quick way to quickly test applying a patch file to a version, and then run PHPUnit on it. Bash Aliases and scripting to the rescue. We had already outlined in our spreadsheet what EDD Core version got which patch. &lt;strong&gt;Patch, test, un-patch, repeat&lt;/strong&gt; Started off with a bash script that took two arguments: EDD Version and Patch file name. &lt;em&gt;A quick bash alias to make the typing shorter&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;alias testpatch=&quot;bash ~/scripts/testpatch&quot;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Then this little file in my &lt;code&gt;~/scripts&lt;/code&gt; folder&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;#!/usr/bin/env bash
if [ $# -lt 2 ]; then
echo &quot;usage: $0 &amp;lt;edd_version&amp;gt; &amp;lt;patch name&amp;gt;&quot;
exit 1
fi&lt;/p&gt;
&lt;p&gt;VER=$1
PATCH=$2
git checkout $VER
git apply -v ~/Dropbox/Add\ Ons/patches/Core/$PATCH
phpunit
git apply -Rv ~/Dropbox/Add\ Ons/patches/Core/$PATCH&lt;/p&gt;
&lt;p&gt;And now I can type something like the following to test version 2.3.6 with the file args.patch:&lt;/p&gt;
&lt;p&gt;$ testpatch 2.3.6 args.patch&lt;/p&gt;
&lt;p&gt;This ensured we never broke the unit tests in our changes. We still had some manual testing to do, but this was a good start, and also allowed us to quickly test the patch files.&lt;/p&gt;
&lt;h3&gt;Deploying&lt;/h3&gt;
&lt;p&gt;I used two bash alias/script combinations for Deploying. One to do all the commits to the master branch of the repositories, and one to tag the new version after I had done the version bumps. They were: &lt;strong&gt;Committing&lt;/strong&gt; &lt;em&gt;The alias for committing the repo I&apos;m currently on&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;alias committhis=&quot;git commit -am &apos;Better query arg handling&apos; &amp;amp;&amp;amp; git push origin master&quot;&lt;/p&gt;
&lt;p&gt;No script needed here, just some combined commands. &lt;strong&gt;Tagging&lt;/strong&gt; &lt;em&gt;The alias for tagging the repo I&apos;m currently on&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;alias tagthis=&quot;bash ~/scripts/tagthis&quot;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The script to tag&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;#!/usr/bin/env bash
if [ $# -lt 1 ]; then
echo &quot;usage: $0 &amp;lt;version&amp;gt;&quot;
exit 1
fi&lt;/p&gt;
&lt;p&gt;VER=$1
git tag -a $VER -m &apos;Tagging $VER&apos; &amp;amp;&amp;amp; git push origin $VER&lt;/p&gt;
&lt;p&gt;This let me type a command like:&lt;/p&gt;
&lt;p&gt;$ tagthis 1.1.1&lt;/p&gt;
&lt;p&gt;And a tag would be created in GitHub for use later. The rest of the process was a manual uploading of .zip files and publishing the Download Updates. I have no idea how long it would have taken it to do this process without these little scripts, but I&apos;d estimate it would have take quite a bit longer. And with this type of consistency (not typing manually over and over), you help mitigate the risk of making a typo.&lt;/p&gt;
&lt;h3&gt;The After Action Review&lt;/h3&gt;
&lt;p&gt;So, this is the first time we&apos;ve had to do this massive of an effort to release a large number of updates. It&apos;s unprecedented really. Because of this, we have some takeaways that we&apos;re going to look to institute in our team.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Better Development Workflow&lt;/p&gt;
&lt;p&gt;Wether it&apos;s a super popular repository, or an extremely obscure one, we need to implement a consistent workflow starting with issue branches, pull requests, and nothing being in master branches until it&apos;s 100% tested and ready for release.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consistent naming conventions&lt;/p&gt;
&lt;p&gt;The biggest issue here was with Repositories named in Camel Case, but deployable folders being all lowercase. This just caused some manual work that would have been safer had it been consistent.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Front-End Testing&lt;/p&gt;
&lt;p&gt;Lower on the list, but we have discussed implementing Selenium Suites for testing front-end changes. The largest issues with this release was the changes affected outputted HTML to the end user, which sometimes isn&apos;t as easily tested with PHPUnit.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Overall I&apos;m &lt;strong&gt;&lt;em&gt;extremely&lt;/em&gt;&lt;/strong&gt; happy with the way the team stepped up to handle Support and other development issues while Pippin and I took care of these changes. When we needed something, they were there to help out and kept asking what they could to do help more.&lt;/p&gt;
</content:encoded></item><item><title>Getting Feedback is About More than Asking for It</title><link>https://chrisk.io/posts/getting-feedback-is-about-more-than-asking-for-it/</link><guid isPermaLink="true">https://chrisk.io/posts/getting-feedback-is-about-more-than-asking-for-it/</guid><description>The other day I was driving home from the coffee shop on lunch break. &quot;How&apos;s My Driving?&quot;, was staring me right in the face in bold black letters on a…</description><pubDate>Sun, 19 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The other day I was driving home from the coffee shop on lunch break. &quot;How&apos;s My Driving?&quot;, was staring me right in the face in bold black letters on a yellow background. Chances are you&apos;ve seen one of these stare you down too. A recourse to penalize bad drivers representing the company, or praise those who are doing a great job. The funny thing is, I was behind that vehicle for a good 2 minutes waiting for the light to change so I could get home. Had that driver done something that warranted me calling the company driver hotline, however, I&apos;d be at a loss. You see, the phone number, was a &quot;1-800&quot; number and didn&apos;t spell anything catchy. The vehicle ID number? Yeah it contained 2 letters and 7 numbers. The license plate, could have read that too, but I was already looking at the phone number, which was on the edge of the bumper, not near the license plate so I could see both at the same time.&lt;/p&gt;
&lt;p&gt;See this company wanted feedback...they&apos;d never get it from me! They&apos;d never get it because they are making it too difficult to meet the customer where they are at.&lt;/p&gt;
&lt;p&gt;If a driver needs to be reported, odds are it&apos;s by another person behind the wheel, who has hundreds of other things to be paying attention to than trying to type a 1800 number into their phone and then remember a 9 character ID, all while remaining in sight of the vehicle is they need any more data.&lt;/p&gt;
&lt;p&gt;You see, they wanted feedback, but were making it too difficult to give it.&lt;/p&gt;
&lt;h3&gt;Feedback is about the customer, not the company&lt;/h3&gt;
&lt;p&gt;Many people and companies make the mistake of thinking that customer feedback is about the product. Really, the process of getting feedback is about the customer, the results of that feedback are about the product.&lt;/p&gt;
&lt;p&gt;The bumper sticker above, had it contained a phone number that was phonetically pronounceable (a phone number that spells something) and had a 4 digit ID number (instead of 9), is something the human brain can remember. They were more focused on getting feedback, than making the feedback easy to provide.&lt;/p&gt;
&lt;h3&gt;Respect Their Time&lt;/h3&gt;
&lt;p&gt;One thing to remember when asking for feedback is, you are asking the responder to sacrifice their time to give it to you. It&apos;s not free by any means. Get to the point, deliver your message quickly, and keep the length to a minimum. If the person wants to provide more feedback, give the opportunity, but do not require it.&lt;/p&gt;
&lt;h3&gt;Meet them Where They Are&lt;/h3&gt;
&lt;p&gt;Does your feedback strategy allow for easy access on mobile devices? You better hope so. A surprisingly large number of people are going &apos;Mobile Only&apos;. In fact, a great Medium article published about &quot;The new ESPN.com&quot; had this to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For instance, 61% of January’s 94 million users were mobile only… meaning that roughly 57 million fans only interacted with our products on a mobile device. Wild.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don&apos;t think I can come up with a better proof to meet your customers where they are than that. I&apos;d encourage you to &lt;a href=&quot;https://medium.com/@ryanspoon/this-is-the-new-espn-com-cb239d68fe8f&quot;&gt;go read the entire article&lt;/a&gt;. It&apos;s a great read about updating a giant in the publishing world.&lt;/p&gt;
&lt;h3&gt;Open and Closed Case&lt;/h3&gt;
&lt;p&gt;&quot;Explain&quot;. My all time LEAST favorite feedback field to see. Especially when it&apos;s &apos;Required&apos;. Being that we&apos;ve already identified that our customer&apos;s time is valuable, let&apos;s not waste it with needless textareas that get in their way. Let them answer briefly, and if follow up is needed, take care of it then.&lt;/p&gt;
&lt;p&gt;A good balance between Open and Closed questions are key. Closed questions being ones that have limited and predefined answers for the user to choose from. Open questions being the big text box for them to fill in. This does not mean use ALL closed questions, just find the balance that works best for your users.&lt;/p&gt;
&lt;h3&gt;So What Next?&lt;/h3&gt;
&lt;p&gt;Personally, I don&apos;t have a ton of hard numbers of where you should go, but Survey Monkey (a company dedicated to streamlining the customer feedback process), has a great infographic from 2014 that might give you some hints.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.surveymonkey.com/blog/en/blog/2014/04/08/whos-taking-customer-feedback-surveys/&quot;&gt;&lt;img src=&quot;/images/blog/FeedbackHabitsFINAL.png&quot; alt=&quot;Survey Monkey gives us some insight into how people treat Customer Satisfaction Surveys.&quot; /&gt;&lt;/a&gt; Survey Monkey gives us some insight into how people treat Customer Satisfaction Surveys.&lt;/p&gt;
&lt;h5&gt;What is one thing you are doing, or can do, to help encourage customer feedback and interaction?&lt;/h5&gt;
</content:encoded></item><item><title>Protect All the Reputations</title><link>https://chrisk.io/posts/protect-all-the-reputations/</link><guid isPermaLink="true">https://chrisk.io/posts/protect-all-the-reputations/</guid><description>When developing software, particularly web applications, you are hardly giving your product to the end user. There&apos;s typically a relationship that looks…</description><pubDate>Thu, 09 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When developing software, particularly web applications, you are hardly giving your product to the end user. There&apos;s typically a relationship that looks more like:&lt;/p&gt;
&lt;p&gt;You › Business › Customer&lt;/p&gt;
&lt;p&gt;Sure, the people you are selling to are &apos;customers&apos; to you, but to their customers, they are the business. So why is this important? Because &lt;em&gt;&lt;strong&gt;decisions you make affect your customer&apos;s reputation.&lt;/strong&gt;&lt;/em&gt; Depending on the type of software you write, your decisions can have a massive affect on the success or failure of another business. I happen to know...I write plugins that handle eCommerce and Social Media management. One little error in my code and their either lose money or followers. Both of which are hard to regain in the competitive space online. So how do I make sure I help protect my reputation with my customers, by looking out for their reputation?&lt;/p&gt;
&lt;h3&gt;It all starts with the support&lt;/h3&gt;
&lt;p&gt;Top notch support is something that businesses look for. If they are making a living by using their product, they expect you to support it, and support it well. This is one of the biggest positive responses we get on the &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads Team&lt;/a&gt;. We&apos;re dedicated to offering best in industry support. Can you please everyone? No. At the end of the day, offering responsive, polite, and &lt;strong&gt;correct&lt;/strong&gt; support will win over the trust of your customers every day.&lt;/p&gt;
&lt;h3&gt;Commitments to Code&lt;/h3&gt;
&lt;p&gt;Things like maintaining Backwards Compatibility, Unit Testing, Extensibility, and User Experience all build up to a solid reputation as a product. Without these things in place, the trust that your software can do what your customers will need dwindles. If you have the ability to run unit tests, do it. It helps instill trust in your users that you&apos;re making sure most aspects of the application are working still, even though you only made a small change. There was a bit of a discussion happening in the WordPress world about a month ago, based off the article &lt;a href=&quot;https://tommcfarlin.com/code-quality-is-not-a-feature/&quot;&gt;&quot;Code Quality is Not a Feature&quot; by Tom McFarlin&lt;/a&gt;. I 100% agree, it&apos;s not a feature, but is something that people will feel more comfortable with using in their business to represent themselves.&lt;/p&gt;
&lt;h3&gt;Eat your own dog food&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Eating_your_own_dog_food&quot;&gt;Dogfooding&lt;/a&gt; is a term used to describe using your own product as an end user, not just in development. Before every release of Easy Digital Downloads or &lt;a href=&quot;https://chrisk.io/PPP&quot;&gt;Post Promoter Pro&lt;/a&gt;, I run them on my own sites for a few days or weeks prior. I do this mainly for 2 reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;People know I do this, and if I&apos;m confident enough to put it on my own site, it makes them feel like I&apos;m committed to the quality of the product.&lt;/li&gt;
&lt;li&gt;If someone is going to see a bug, I&apos;m the best person to know what might be causing it, at that moment. Bug reports are inconsistent, and sometimes lacking details. By seeing them myself early, and in an environment I have full access to I can try and catch them before a customer does, and then their customer does.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Take pride in THEIR success&lt;/h3&gt;
&lt;p&gt;When I hear that something I built is helping a customer succeed, I&apos;ve succeeded. There&apos;s not much more to that. Whether I&apos;m getting credit or not, in the end, my objective is complete:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Help a person achieve their goals, using my passion for writing software.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I love it when I get to a checkout screen and I can tell it&apos;s powered by Easy Digital Downloads. If I see a Tweet from someone I know uses Post Promoter Pro...I get a sense of satisfaction in knowing I helped them achieve their goals.&lt;/p&gt;
&lt;h3&gt;You&apos;re representing more than just yourself&lt;/h3&gt;
&lt;p&gt;The product you produce and services you provide, represent yourself first and foremost. Depending on your industry though, your efforts &lt;em&gt;MAY&lt;/em&gt; represent your customer. Testimonials, sales, referrals, and success in the product or service industry is based off how well you manage these reputations and expectations. Understanding this is the first step to delivering a quality experience, alongside your delivered product or service.&lt;/p&gt;
&lt;h5&gt;How are you managing your reputation with your customers? If you asked a customer &lt;em&gt;&lt;strong&gt;today&lt;/strong&gt;&lt;/em&gt;, what would they say is the reason they stick with you?&lt;/h5&gt;
</content:encoded></item><item><title>Prevent additional discounts when renewal discounts are applied</title><link>https://chrisk.io/posts/prevent-discount-codes-with-easy-digital-downloads-software-licensing-renewal-discount/</link><guid isPermaLink="true">https://chrisk.io/posts/prevent-discount-codes-with-easy-digital-downloads-software-licensing-renewal-discount/</guid><description>Update: This is now a feature that&apos;s built directly into the Software Licensing add-on for Easy Digital Downloads . It can be accessed in Downloads &gt;…</description><pubDate>Tue, 07 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; This is now a feature that&apos;s built directly into the &lt;a href=&quot;https://chrisk.io/EDDSL&quot;&gt;Software Licensing add-on for Easy Digital Downloads&lt;/a&gt;. It can be accessed in Downloads &amp;gt; Settings &amp;gt; Extensions &amp;gt; Software Licensing. From there check the box for &quot;Disable Discount Codes on Renewals&quot;.&lt;/p&gt;
&lt;p&gt;Recently I had a question about &lt;a href=&quot;https://chrisk.io/EDDSL&quot;&gt;Easy Digital Downloads - Software Licensing&lt;/a&gt; that I hadn&apos;t thought about before. When offering a renewal discount, how can we prevent any additional discounts from being applied to the cart? You see, depending on the discount code someone has, you could be losing money if you offer a discount to renew a license, and then a discount code is used on top of that.&lt;/p&gt;
&lt;p&gt;So here&apos;s the quick snippet, and what it looks like on the front end:&lt;/p&gt;
&lt;p&gt;function kfg_check_if_is_renewal( $return ) {&lt;/p&gt;
&lt;p&gt;if ( EDD()-&amp;gt;session-&amp;gt;get( &apos;edd_is_renewal&apos; ) ) {&lt;br /&gt;
edd_set_error( &apos;edd-discount-error&apos;, __( &apos;This discount is not valid with renewals.&apos;, &apos;edd&apos; ) );&lt;br /&gt;
return false;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;return $return;&lt;/p&gt;
&lt;p&gt;}&lt;br /&gt;
add_filter( &apos;edd_is_discount_valid&apos;, &apos;kfg_check_if_is_renewal&apos;, 99, 1 );&lt;/p&gt;
&lt;p&gt;Then if a customer tries to apply a discount code, with a renewal, they&apos;ll see the following:&lt;br /&gt;
&lt;img src=&quot;/images/blog/Screen-Shot-2015-04-07-at-11.04.01-PM.png&quot; alt=&quot;Screen Shot 2015-04-07 at 11.04.01 PM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you would like a single-file plugin for this, you can &lt;a href=&quot;https://github.com/easydigitaldownloads/library/blob/master/checkout/prevent-discounts-with-sl-renewals.php&quot;&gt;get it from the EDD Library&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Coding In Someone Else&apos;s Kitchen</title><link>https://chrisk.io/posts/coding-in-someone-elses-kitchen/</link><guid isPermaLink="true">https://chrisk.io/posts/coding-in-someone-elses-kitchen/</guid><description>Recently I was watching an episode of Top Chef, from Season 1. Yep, All the way back. In fact it may have been episode one. Anyway, watch this scene, where…</description><pubDate>Wed, 11 Mar 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently I was watching an episode of Top Chef, from Season 1. Yep, All the way back. In fact it may have been episode one. Anyway, watch this scene, where a contestant was given an opportunity to work for a world renown chef for 30 minutes (or until the chef decided they weren&apos;t cutting it). This contestant was asked to taste the sauce he was making, dipped his finger in to taste, and was &lt;em&gt;immediately&lt;/em&gt; shown the door. It lead to this awkwardly tense moment.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.hulu.com/embed.html?eid=lzesmv3xrxgccwfpugweew&amp;amp;et=853&amp;amp;st=799&amp;amp;it=i809&quot;&gt;Watch the video here.&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Coding in someone else&apos;s kitchen&lt;/h3&gt;
&lt;p&gt;Software development, at it&apos;s core, is a lot like cooking. Everyone has their own take on how something should be done. It can even be difficult repeating EXACTLY what we did last time. Just because you make one great cake, doesn&apos;t mean the next will turn out perfect. In software, these are bugs...in cooking, we&apos;ll refrain from calling them &apos;bugs&apos; and just refer to them as &apos;variances&apos; ;).&lt;/p&gt;
&lt;p&gt;If you were to walk into the kitchen of another chef/cook, at the end of the day, it&apos;s their domain. When producing end results, the customer&apos;s don&apos;t know it was you who produced the dish, they think it&apos;s the head chef, so their reputation is on the line. The same goes for contributing to open source software.&lt;/p&gt;
&lt;h3&gt;Respect the chef&lt;/h3&gt;
&lt;p&gt;In the commit history of the project, sure, your name shows. When it comes to the larger release notes, the primary developer or team, puts their name on the overall project. That means your code represents them. With that in mind, here&apos;s five things to remember when you submit code to someone else&apos;s project:&lt;/p&gt;
&lt;h4&gt;1. Coding standards are not universal&lt;/h4&gt;
&lt;p&gt;This is a hotbed of controversy in development. Spaces vs. Tabs. Camel Case vs. Snake Case. 2 vs. 4. I could go on, but you get the picture. The only thing that matters when contributing, is that you follow the projects defined standards. If they ask you to update a change to match, please oblige. It&apos;s a matter of consistency.&lt;/p&gt;
&lt;h5&gt;...but,&lt;/h5&gt;
&lt;p&gt;If the project doesn&apos;t have a standard, suggest they implement one and use a &lt;a href=&quot;http://editorconfig.org/&quot;&gt;.editorconfig&lt;/a&gt; file.&lt;/p&gt;
&lt;h4&gt;2. Suggestions are not personal&lt;/h4&gt;
&lt;p&gt;Sometimes, when you work &lt;em&gt;really&lt;/em&gt; hard on a set of changes, it&apos;s hard not to take suggestions personal. You feel like you&apos;ve done a great job, thought of all the cases, and even double checked it...but when the project lead comes back and suggests a few things, it can take the wind from your contribution sales. Don&apos;t let it, at the end of the day they are more intimate with the code than most people, so their suggestions may be taking other issues into consideration.&lt;/p&gt;
&lt;h5&gt;...but,&lt;/h5&gt;
&lt;p&gt;As always though, if you have a valid case for your changes, explain it in a detailed and non-emotional response for the best reception.&lt;/p&gt;
&lt;h4&gt;3. Pull Requests can sit...for a while&lt;/h4&gt;
&lt;p&gt;This is more specific to GitHub but for any requested changes, keep in mind there is more than just your change queued in the pipe. At one point on &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads&lt;/a&gt; we had over 25 pull requests waiting for review. To be honest, it&apos;s on purpose. Not that we keep things waiting, but that we set aside a specific time of our week to go through open pull requests to review them. If we reviewed everyone as they came in, we&apos;d never get anything done. There&apos;s a mental state to be in when doing code reviews, to allow for maximum quality.&lt;/p&gt;
&lt;h5&gt;...but,&lt;/h5&gt;
&lt;p&gt;If you think it&apos;s been excessively long...just ping them on the issue/ticket. See if they need anything else.&lt;/p&gt;
&lt;h4&gt;4. Don&apos;t over-extend yourself&lt;/h4&gt;
&lt;p&gt;One of the most frequent issues, is absentee contributors. It&apos;s ok, as a repo owner, we understand you are doing this in your own time, and usually for free. We are fine with it, and totally get it. Sometimes the status of an issue or change can be lost though as we wait for a commit/change or comments/updates. If you feel you are overextended and won&apos;t get to something in a timely manor, just let them know in a comment with your timeframe, or if you need to pass along the work to someone else. It helps stop the &apos;Where are we at with this?&apos; question.&lt;/p&gt;
&lt;h5&gt;...but,&lt;/h5&gt;
&lt;p&gt;There&apos;s not really an alternative here, it&apos;s about the owner respecting your time and you respecting their timelines. Work it out, play nice and it&apos;ll be ok.&lt;/p&gt;
&lt;h4&gt;5. Focus on your area of expertise&lt;/h4&gt;
&lt;p&gt;We all have our own areas of proficiency. When finding projects to contribute to, find areas you can assist where you can provide the most impact. If you are a great JavaScript developer, go look through the front end files and see where you can offer improvements to the performance or reusability. Sometimes they may not always agree with your changes, and thats when we have to go back to #2. If you can offer yourself as a Subject Matter Expert (SME), work with the repo owner to help own those issues, if you have the time (See #4).&lt;/p&gt;
&lt;h5&gt;...but,&lt;/h5&gt;
&lt;p&gt;If the project already has someone with your expertise, work with them to help review each others work. Unchecked work is dangerous, and if someone of a high skill level is being reviewed by someone with less skill, things will get missed. Two high level developers working in tandem can be a really powerful thing.&lt;/p&gt;
&lt;h3&gt;Go Fourth and Contribute!&lt;/h3&gt;
&lt;p&gt;That&apos;s about it...go find somewhere to contribute! I&apos;d never live it down if I didn&apos;t say &lt;a href=&quot;https://github.com/easydigitaldownloads/Easy-Digital-Downloads/issues&quot;&gt;Easy Digital Downloads&lt;/a&gt; is a great place to start.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
</content:encoded></item><item><title>Code Snippet: Show blog ID in admin header</title><link>https://chrisk.io/posts/code-snippet-show-blog-id-admin-header/</link><guid isPermaLink="true">https://chrisk.io/posts/code-snippet-show-blog-id-admin-header/</guid><description>Just recently I ran into a case where I had to quickly look something up in the database of my WordPress development environment. I typically do this via a…</description><pubDate>Fri, 20 Feb 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Just recently I ran into a case where I had to quickly look something up in the database of my WordPress development environment. I typically do this via a program called Sequel Pro, which helps give some visualization to your database. I love Command Line tools, but sometimes I prefer the visuals to do some troubleshooting.&lt;/p&gt;
&lt;p&gt;If you&apos;ve ever looked at a WordPress database, you&apos;ll typically see tables like &lt;code&gt;wp_posts, wp_postameta, and wp_options&lt;/code&gt;. In multisite however, things like the posts table, postmeta and options are in tables that contain the &lt;code&gt;blog_id&lt;/code&gt;, giving us &lt;code&gt;wp_3_posts, wp_3_postmeta, and wp_3_options&lt;/code&gt;. No problem at all if your multisite only has a couple sites setup, but when you use it for your development environment, you get something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2015-02-20-at-11.32.51-AM.png&quot; alt=&quot;Screen Shot 2015-02-20 at 11.32.51 AM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Determining what blog ID you are looking at, isn&apos;t quite easy. So here&apos;s a quick snippet that will drop the current blog ID in the admin header, like so:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2015-02-20-at-11.35.06-AM.png&quot; alt=&quot;Screen Shot 2015-02-20 at 11.35.06 AM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;function kfg_toolbar_blog_id( $wp_admin_bar ) {
$args = array(
&apos;id&apos;    =&amp;gt; &apos;blog_id&apos;,
&apos;title&apos; =&amp;gt; &apos;Blog #&apos; . get_current_blog_id()
);
$wp_admin_bar-&amp;gt;add_node( $args );
}
add_action( &apos;admin_bar_menu&apos;, &apos;kfg_toolbar_blog_id&apos;, 999 );&lt;/p&gt;
</content:encoded></item><item><title>Don&apos;t Settle for Broken Windows</title><link>https://chrisk.io/posts/dont-settle-broken-windows/</link><guid isPermaLink="true">https://chrisk.io/posts/dont-settle-broken-windows/</guid><description>Small or large...a broken window is still broken. The same principal applies to your code. Small or large, a bug exists and needs to be fixed.</description><pubDate>Tue, 27 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In one of my posts a while back about my &lt;a href=&quot;https://chrisk.io/2014/05/must-books-software-development/&quot;&gt;must have books on software development&lt;/a&gt;, I listed &apos;&lt;a href=&quot;https://chrisk.io/Pragmatic&quot;&gt;The Pragmatic Programmer&lt;/a&gt;&apos; as the 2nd book. Yes, I still recommend it. I still try and re-read it every year or two...and more recently one of the first metaphors listed in the book guided me, and I didn&apos;t even realize it. Before you go on, &lt;a href=&quot;https://pragprog.com/the-pragmatic-programmer/extracts/software-entropy&quot;&gt;read this excerpt/concept from the book about Software Entropy&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&quot;Don’t Live with Broken Windows&quot;&lt;/h3&gt;
&lt;p&gt;So now that you&apos;ve read it, the main concept I love is the phrase &quot;Don&apos;t Live with Broken Windows&quot;. Small or large...a broken window is still broken. Small cracks lead to bigger problems. So how is this relevant and why is this post better than just picking up the book? I&apos;m going to tell you a little story about my new job with &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads&lt;/a&gt; (EDD).&lt;/p&gt;
&lt;p&gt;I&apos;d been working on the EDD team for about the past year and a half, as a contributor. Along with this came submitting patches, commenting on issues, but I never really &apos;owned&apos; the code base. I was not an outsider, but I wan&apos;t an insider either. It&apos;s a weird spot. The day I joined as an official EDD employee, things instantly changed.&lt;/p&gt;
&lt;h3&gt;Fixing broken windows&lt;/h3&gt;
&lt;p&gt;We are using Travis-CI as a way to run our unit tests on all merges, pull requests, and commits. If you aren&apos;t doing it for your open source project, go do it. It&apos;s free if you are open source on GitHub. Our build for EDD has been failing for a while, and because of that, our GitHub repo showed that in a nice red badge..that we chose to put there. In reality, the build was failing for a super simple reason, it only took a 1 line fix and it wasn&apos;t even failing hard. The application worked, everything was fine, but there was no failure or corruption of data. No &lt;em&gt;fatal error&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The most interesting thing happened in a conversation with another team member. I had asked him about how a PR he submitted had broken the build...and his response (at no fault to him) was &quot;...and that&apos;s different than normal how...?&quot;.&lt;/p&gt;
&lt;p&gt;What he hadn&apos;t realized was, the first week I started, I focused efforts on improving, and making sure our build was passing, at every moment. His comment though, wasn&apos;t unique to him. The team had just grown &lt;em&gt;content&lt;/em&gt; with the fact that our build failed. When I told him the change to fix it he asked why we hadn&apos;t fixed that a long time ago!? The &apos;broken window&apos; had gone unfixed for so long, we all just assumed it was a lost cause.&lt;/p&gt;
&lt;h3&gt;Fix or log it when you see it&lt;/h3&gt;
&lt;p&gt;So how do we stop being content? Well, that&apos;s up to each person individually but there are a few keys that I think help.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1) When you see an issue, log it:&lt;/strong&gt;&lt;br /&gt;
This is important because an unnamed problem is an forgotten problem. the more detailed the better. This way you can track it down faster in the future.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2) Assign a timeframe, immediately:&lt;/strong&gt;&lt;br /&gt;
Software development isn&apos;t written in stone. Milestones and release dates can be changed. However, if you never assign a milestone or release date, it&apos;s more likely to get ignored. On the EDD Team, I will periodically go through un-milestoned issues and put them in a future release. Even if it&apos;s going to change later, at least it&apos;s on the radar somewhere.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3) The only &apos;bad&apos; issue, is the one not created:&lt;/strong&gt;&lt;br /&gt;
I know some devs or project owners get annoyed at petty issues or tickets, but I&apos;d rather have an issue raised and marked as &apos;wontfix&apos; or &apos;Not a Bug&apos;, than not see them at all.&lt;/p&gt;
&lt;p&gt;Post Image courtesy of &lt;a href=&quot;http://www.flickr.com/photos/mikecogh/&quot;&gt;Michael Coghlan via Flickr &amp;amp; Creative Commons&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Reducing PHPUnit test times with Travis-CI</title><link>https://chrisk.io/posts/reducing-phpunit-test-times-travis-ci/</link><guid isPermaLink="true">https://chrisk.io/posts/reducing-phpunit-test-times-travis-ci/</guid><description>A few months ago I had proposed that the Easy Digital Downloads project expand our PHP/WordPress version matrix for our Travis-CI builds. The problem we…</description><pubDate>Thu, 01 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A few months ago I had proposed that the &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads&lt;/a&gt; project expand our PHP/WordPress version matrix for our Travis-CI builds. The problem we quickly ran into, is that with the existing matrix, our builds were taking ~1.25 hours to complete. This was just not a realistic means of getting feedback on a git push. In order be effective at providing feedback, it needs to be something you can wait for without using up a drastic amount of time.&lt;/p&gt;
&lt;h3&gt;Coverage For the Win/Loss&lt;/h3&gt;
&lt;p&gt;After some investigation, it was found that the biggest hit to the build performance, was code coverage. For those that don&apos;t know, code coverage is a means of monitoring your tests, and telling you what percentage of your code is (or isn&apos;t) tested. This allows you to build more tests to test a greater percentage of your code. This is actually a very important statistic, as it lends to the credence of your unit test passing. For example, let&apos;s say we have two projects, Project X and Project Y. They have the following unit test pass %:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Project X:&lt;/strong&gt; 100% - 10/10 Tests Passed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Project Y:&lt;/strong&gt; 100% - 10/10 Tests Passed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the surface, they both pass 10 out of 10 tests...but what if we throw code coverage into the mix:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Project X:&lt;/strong&gt; 100% - 10/10 Tests Passed - 85% Code Coverage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Project Y:&lt;/strong&gt; 100% - 10/10 Tests Passed - 45% Code Coverage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Are you more prone trust a codebase that has 85% of it&apos;s code tested, and passing, or less than half? I&apos;ll admit, we&apos;re working to get the EDD codebase up to a better percentage of code coverage, but really that&apos;s another story and another blog post. For now we&apos;ll just focus on why it&apos;s important to get code coverage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But every time?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is the decision we made. With Code Coverage, a single unit test took ~5 minutes to complete. Cross that with 3 PHP versions and 6 Combinations of WordPress (3 versions, with and without Multisite), and you&apos;ve got 18 tests, @ 5 minutes each. That is a LONG time to wait for a built to complete.&lt;/p&gt;
&lt;p&gt;Without code coverage reporting, our suite builds in ~30 seconds (on average). Now, multiply by 18 combinations of builds, and we&apos;ve got a 9 minute build time. That&apos;s awesome, the problem is, we were only testing PHP 5.3, 5.4, and 5.5 alongside WordPress 4.0, 4.1, and the latest nightly build. Why isn&apos;t this enough? Well, PHP 5.6 is on the edge of being provided by some hosts, so we should get ahead of that, and our &apos;Required Version&apos; of WordPress is 3.9.2, and we weren&apos;t testing for it.&lt;/p&gt;
&lt;p&gt;So how do we maximize the matrix, while maintaining code coverage reporting?&lt;/p&gt;
&lt;h3&gt;Only running Code Coverage on Pull Requests&lt;/h3&gt;
&lt;p&gt;Yep, after looking over the documentation of Travis-CI, I found a way that you could identify when a build being run is the result of a Pull Request creation/update, versus a commit to a branch. Here&apos;s how we did it.&lt;/p&gt;
&lt;h3&gt;The Files&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;travis.yml&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Travis-CI config file has an entry for &lt;code&gt;script&lt;/code&gt; (what to run as the tests) and &lt;code&gt;after_script&lt;/code&gt; (what to run when complete). Typically you would put the BASH command you want to run here, most likely &lt;code&gt;$&amp;gt; phpunit&lt;/code&gt;. Did you know though, that you can just call a normal bash script too? That&apos;s what we did, like this:&lt;/p&gt;
&lt;p&gt;language: php&lt;/p&gt;
&lt;p&gt;sudo: false&lt;/p&gt;
&lt;p&gt;php:&lt;br /&gt;
- 5.3&lt;br /&gt;
- 5.4&lt;br /&gt;
- 5.5&lt;br /&gt;
- 5.6&lt;br /&gt;
- hhvm&lt;/p&gt;
&lt;p&gt;env:&lt;br /&gt;
- WP_VERSION=latest WP_MULTISITE=0&lt;br /&gt;
- WP_VERSION=latest WP_MULTISITE=1&lt;br /&gt;
- WP_VERSION=4.1 WP_MULTISITE=0&lt;br /&gt;
- WP_VERSION=4.1 WP_MULTISITE=1&lt;br /&gt;
- WP_VERSION=4.0 WP_MULTISITE=0&lt;br /&gt;
- WP_VERSION=4.0 WP_MULTISITE=1&lt;br /&gt;
- WP_VERSION=3.9.2 WP_MULTISITE=0&lt;br /&gt;
- WP_VERSION=3.9.2 WP_MULTISITE=1&lt;/p&gt;
&lt;p&gt;before_script:&lt;br /&gt;
- bash bin/install-wp-tests.sh wordpress_test root &apos;&apos; localhost $WP_VERSION&lt;/p&gt;
&lt;p&gt;script:&lt;br /&gt;
- ./travis-tests.sh&lt;/p&gt;
&lt;p&gt;after_script:&lt;br /&gt;
- ./travis-after.sh&lt;/p&gt;
&lt;p&gt;The contents of our scripts are as follows:&lt;br /&gt;
&lt;strong&gt;travis-tests.sh&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;#!/bin/bash
if [ &quot;${TRAVIS_PULL_REQUEST}&quot; = &quot;false&quot; ]
then
phpunit
else
phpunit --coverage-clover=coverage.clover
fi&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;travis-after.sh&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;#!/bin/bash
if [ &quot;${TRAVIS_PULL_REQUEST}&quot; != &quot;false&quot; ]
then
wget https://scrutinizer-ci.com/ocular.phar
php ocular.phar code-coverage:upload --format=php-clover coverage.clover
fi&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;What this essentially does now, is when a signal comes into Travis-CI to do a build, it checks the environment variable &lt;code&gt;${TRAVIS_PULL_REQUEST}&lt;/code&gt;, which when there is a pull request present is set to the pull request number, otherwise it&apos;s &lt;code&gt;false&lt;/code&gt;. This allows us to only run Code Coverage during a Pull Request, and for all other commits/push builds, simply run the basic unit tests, looking for breaking points.&lt;/p&gt;
&lt;p&gt;With these faster tests, we can now have a matrix that is &lt;code&gt;5 x 8&lt;/code&gt;, or 40 builds, instead of 18, and finish in a fraction of the time. This gives us maximum compatibility checks, but still allows us to get coverage reports before merging in a Pull Request. Granted, our Pull Request builds take ~2 hours to complete, however these are usually items that are less necessary to be a quick response, as Pull Requests typically aren&apos;t merged until a few hours after submitting them (at best). And on top of that, when a Pull Request is submitted, 2 builds are done, 1 Full build with code coverage, and 1 without, so we can get a quick check of it to make sure that the tests pass, and then wait to make sure we&apos;ve got ample code coverage in the code to be merged.&lt;/p&gt;
&lt;p&gt;So that&apos;s just a little bit of what we decided and executed as a team to maximize our matrix, without paying the penalty of the build times. Hope you find it useful, and if you have any suggestions, I&apos;d be happy to see them in the comments.&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
&lt;p&gt;Post Image by &lt;a href=&quot;http://www.flickr.com/photos/jepoirrier/&quot;&gt;Jean-Etienne Minh-Duy Poirrier&lt;/a&gt; via Creative Commons and Flickr&lt;/p&gt;
&lt;p&gt;UPDATE: As a discussion opened on Twitter, it was also recognized by &lt;a href=&quot;https://twitter.com/bradt&quot;&gt;Brad Touesnard&lt;/a&gt; identified, we could also look into only running code coverage on one of the build matrix items. I&apos;m going to be looking into seeing if we can optimize this way next, after I discuss it with the team.&lt;/p&gt;
</content:encoded></item><item><title>Not Everything Is a Nail</title><link>https://chrisk.io/posts/not-everything-nail/</link><guid isPermaLink="true">https://chrisk.io/posts/not-everything-nail/</guid><description>Often times, as a developer, I&apos;m asked the question we all dread... Do you have a minute? I have an idea I want to run past you. &lt;insert generic idea with…</description><pubDate>Sat, 29 Nov 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Often times, as a developer, I&apos;m asked the question we all dread...&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do you have a minute? I have an idea I want to run past you.&lt;/p&gt;
&lt;p&gt;&amp;lt;insert generic idea with slight twist here&amp;gt;&lt;/p&gt;
&lt;p&gt;How long would that take you?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Be honest, it&apos;s happened once or twice this month, right? Yep, me too. Often times, the first thing I go to, is how long it would actually take me to dev the work. We&apos;re all experts in something that we feel we can do better than everyone else..but I&apos;m getting ahead of myself. Let me tell you a quick example that proves my point.&lt;/p&gt;
&lt;h3&gt;Hey dear, I have a question...&lt;/h3&gt;
&lt;p&gt;I&apos;m sure, that&apos;s a question many of use have heard from our partners at some point in their relationship, so I wasn&apos;t really dreading it, until this was the question:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/Yg9vPghgox-3000x30001.png&quot; alt=&quot;Yg9vPghgox-3000x3000&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So there it was, the dreaded, &quot;How long/much does it take to build X.&quot; To lay a little background my wife runs a Co-Op, in which she collects people that want to buy a lot from the same company, gathers their orders, then places one large order to reduce costs. Technically, she&apos;s a wholesaler. Sometimes, when there aren&apos;t quite enough orders to fill the minimums, she&apos;ll front the cost and resell the remainders later. Her previous method was very time consuming and not easy to manage.&lt;/p&gt;
&lt;p&gt;As a developer on &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads&lt;/a&gt;, I thought, &quot;This should be EASY. I&apos;ll just get access to the USPS API, build a quick shipping plugin, get a theme setup, and she&apos;ll be off to the races selling her extras online without a care.&quot; So I thought...as I started planning the work, between my job, family time, chores around the house, holidays...yep, this wasn&apos;t going to be quick and would likely take a few iterations to get right.&lt;/p&gt;
&lt;h3&gt;Enter...WooCommerce&lt;/h3&gt;
&lt;p&gt;I traded in my &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;EDD&lt;/a&gt; hat for a bit, installed &lt;a href=&quot;http://www.woothemes.com/woocommerce/&quot;&gt;WooCommerce&lt;/a&gt; and even bought the WooThemes USPS Shipping plugin. I went to the &apos;Dark Side&apos;...and it worked out perfectly. Within hours, my wife was publishing her extras, and within 24 hours, made her first sale. She&apos;s made several since, and minus a small $0.30 issue in shipping, everything has been estimated nearly perfectly. In the end, something I had done, or could do, wasn&apos;t the answer to the question. It existed elsewhere.&lt;/p&gt;
&lt;h3&gt;You aren&apos;t always the answer&lt;/h3&gt;
&lt;p&gt;When we&apos;re passionate about building a product, it becomes our hammer, and every question looks like a nail. In this case I&apos;m a developer on an eCommerce platform, that could do what my wife needed with a little help. The truth of the matter is, someone else has one that worked perfectly for her, and I didn&apos;t have to be that hero. In fact, days after we pushed the site live, &lt;a href=&quot;http://www.woothemes.com/storefront/&quot;&gt;WooThemes shipped their free &apos;Storefront&apos; theme&lt;/a&gt; that&apos;s now powering her store. And with great features that she was amazed by, that again, would have taken me time to build into a theme to integrate with EDD.&lt;/p&gt;
&lt;p&gt;Did it hurt to not use something I&apos;m proud to have worked on...you bet it did. In all reality though, this was less about my ego, and more about getting my &apos;client&apos; what they needed, and that&apos;s the real win.&lt;/p&gt;
&lt;h3&gt;Using the other Hammer&lt;/h3&gt;
&lt;p&gt;There are a few added benefits to using this platform that &apos;competes&apos; with the one I work on. It&apos;s always a good idea to look at your competition, in fact, it&apos;s encouraged. Most likely though, your research is just setting it up in a test area, using it for a day, and then leaving it behind. You never really give it the &apos;daily driver&apos; attempt. Therefore, you miss a TON of good knowledge. Using WooCommerce for my wife&apos;s site has lead to me seeing a different way to do things, which is NEVER a bad idea. Some things, I feel, Easy Digital Downloads does better. There are other areas though where WooCommerce has us beat, and that means we can improve. If I can get you to take away one thing it&apos;s this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[bctt tweet=&quot;Never let your pride in your work stop you from admiring and praising the work of others.&quot;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the end, both &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads&lt;/a&gt; and &lt;a href=&quot;http://www.woothemes.com/woocommerce/&quot;&gt;WooCommerce&lt;/a&gt; are extremely popular and well built pieces of software that the developers can be proud of. I&apos;m just glad I took the opportunity to give the &apos;competition&apos; a shot and see the great work some of my friends have been apart of.&lt;/p&gt;
</content:encoded></item><item><title>Setup DesktopServer with WordPress Trunk</title><link>https://chrisk.io/posts/setup-desktopserver-wordpress-trunk/</link><guid isPermaLink="true">https://chrisk.io/posts/setup-desktopserver-wordpress-trunk/</guid><description>While at WordCamp San Francisco this weekend I had the opportunity to sit down with the Operations Manager for ServerPress, the group behind the popular…</description><pubDate>Fri, 31 Oct 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;While at WordCamp San Francisco this weekend I had the opportunity to sit down with the Operations Manager for ServerPress, the group behind the popular &lt;a href=&quot;http://serverpress.com/downloads/&quot;&gt;DesktopServer&lt;/a&gt; application that helps you quickly setup and manage your local development environments (amongst other amazing features). The first thing I wanted to do was have a &apos;Trunk&apos; install of WordPress so I could get the nightly releases.&lt;/p&gt;
&lt;p&gt;This didn&apos;t seem obvious at first, and there was a guide listed on the ServerPress documentation, but it was somewhat difficult to follow, so I figured I&apos;d lay it out here, step by step.&lt;/p&gt;
&lt;p&gt;We&apos;re going to use the Blueprints feature here, as well as some command line so bear with me.&lt;/p&gt;
&lt;p&gt;Step 1: Prepare your blueprint.&lt;br /&gt;
Create an empty folder on your desktop and name it &lt;code&gt;WordPress (SVN)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Copy the &lt;code&gt;index.html&lt;/code&gt; from the &lt;code&gt;Blank (Non-WordPress)&lt;/code&gt; blueprint to your new &lt;code&gt;WordPress (SVN)&lt;/code&gt; folder. On a Mac this is located in &lt;code&gt;/Applications/XAMPP/blueprints&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://core.svn.wordpress.org/trunk/wp-config-sample.php&quot;&gt;Grab a copy&lt;/a&gt; of the &lt;code&gt;wp-config-sample.php&lt;/code&gt; file and put it in the &lt;code&gt;WordPress (SVN)&lt;/code&gt; folder.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Screen-Shot-2014-10-29-at-10.51.46-PM.png&quot;&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2014-10-29-at-10.51.46-PM-300x194.png&quot; alt=&quot;Your WordPress (SVN) folder should have these two files in it.&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Step 2: Copy your blueprint&lt;/p&gt;
&lt;p&gt;Next, copy that folder to your blueprints directory.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Screen-Shot-2014-10-29-at-11.20.00-PM.png&quot;&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2014-10-29-at-11.20.00-PM-300x186.png&quot; alt=&quot;Add the WordPress (SVN) folder to your blueprints directory&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Step 3: Setup the site&lt;br /&gt;
Start up DesktopServer and choose a new site.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Screen-Shot-2014-10-29-at-10.53.12-PM.png&quot;&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2014-10-29-at-10.53.12-PM-300x239.png&quot; alt=&quot;Choose to create a new site&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Select the blueprint for &quot;WordPress (SVN)&quot;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Screen-Shot-2014-10-29-at-10.54.20-PM.png&quot;&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2014-10-29-at-10.54.20-PM-300x239.png&quot; alt=&quot;Select our newly created blueprint&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What we&apos;ve left with here is now a properly created wp-config.php file with the correct database credentials for this site install.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2014-10-29-at-10.54.55-PM-300x186.png&quot; alt=&quot;Screen Shot 2014-10-29 at 10.54.55 PM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Step 4: Get WordPress&lt;br /&gt;
Now we can go get the WordPress Trunk code.&lt;/p&gt;
&lt;p&gt;Open up your favorite terminal and change directories into where your DesktopServer saves your local sites. Mine happens to be in my home directory in a folder called &quot;WordPress&quot;.&lt;/p&gt;
&lt;p&gt;Once there, go to the site you created, mine was &quot;trunk-testing.dev&quot;. Run the following two commands:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;svn co https://core.svn.wordpress.org/trunk .&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;rm index.html&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;*note, the &apos;.&apos; is important in the first command*&lt;/p&gt;
&lt;p&gt;Step 5: Setup WordPress&lt;br /&gt;
This should give you a copy of WordPress in that newly created local site, and if you open a browser and go to the url (in my case trunk-testing.dev), you should see the following:&lt;br /&gt;
&lt;a href=&quot;/images/blog/Screen-Shot-2014-10-29-at-10.56.40-PM.png&quot;&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2014-10-29-at-10.56.40-PM-300x173.png&quot; alt=&quot;Screen Shot 2014-10-29 at 10.56.40 PM&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Step 6: Make cool stuff&lt;br /&gt;
Now you can develop on trunk!&lt;/p&gt;
&lt;p&gt;As a note, I&apos;ve had a couple discussions with people familiar with the matter and for DesktopServer 4.0, this might become obsolete as they have expanded the capabilities of the platform tremendously. However, until then, this should get you started.&lt;/p&gt;
</content:encoded></item><item><title>Your IDE sucks</title><link>https://chrisk.io/posts/ide-sucks/</link><guid isPermaLink="true">https://chrisk.io/posts/ide-sucks/</guid><description>It&apos;s the hot topic all developers talk about. Their tool sets...and why their toolset is better than yours. Why is better than , and why you need an IDE…</description><pubDate>Fri, 29 Aug 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s the hot topic all developers talk about. Their tool sets...and why their toolset is better than yours. Why &lt;em&gt;[insert IDE here]&lt;/em&gt; is better than &lt;em&gt;[insert another IDE here]&lt;/em&gt;, and why you need an IDE over a simple extensible text editor. What debugging methods you use, somehow, means you are either a hack or a professional. You can try and deny it, it happens whenever two or more developers get within an earshot of each other. Heck, we&apos;ll even jump into a conversation (sometimes leaving the one we&apos;re in), because we overheard &lt;em&gt;&quot;how much better&quot;&lt;/em&gt; something is.&lt;/p&gt;
&lt;p&gt;Guess what?&lt;/p&gt;
&lt;h3&gt;We are ALL wrong&lt;/h3&gt;
&lt;p&gt;As always, it comes down to personal preference, sort of. I say &quot;sort of&quot; because what it really comes down to is efficiency. At the end of the day, whether you build products or work hourly for clients, your time is worth a calculable amount of money. The faster you can get something done, the most money per hour you can make. While personal preference has a lot to do with that, you could be missing something that makes you more efficient.&lt;/p&gt;
&lt;h3&gt;No job is too small&lt;/h3&gt;
&lt;p&gt;I&apos;ll reference a story my father told me about UPS and their package car routes. You&apos;ve probably witnessed it on Mythbusters, a myth about only making right turns. Well according to some sources, this helped eliminate ~4.83[&lt;a href=&quot;#1&quot;&gt;1&lt;/a&gt;] miles from each package car&apos;s yearly mileage.&lt;/p&gt;
&lt;p&gt;Wait, &lt;em&gt;&apos;yearly&apos;&lt;/em&gt;. I typed that right didn&apos;t I?! Yeah I did.&lt;/p&gt;
&lt;p&gt;So why is that a big deal? Because given the fact that they have ~96,000 package cars on the road every year, the total savings of mileage is a bit more impressive. It totals to 464,000 miles[&lt;a href=&quot;#1&quot;&gt;1&lt;/a&gt;], and saved them 51,000[&lt;a href=&quot;#1&quot;&gt;1&lt;/a&gt;] gallons of fuel that year. Given the approximate average of fuel that year was $2.25 per US Gallon[&lt;a href=&quot;#2&quot;&gt;2&lt;/a&gt;], that&apos;s a savings of $1,044,000.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Small improvements, when repeated, can return big gains&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;So why the discussion&lt;/h3&gt;
&lt;p&gt;The point of the story is to re-evaluate your own work flows. I have a general rule. If I run a command more than twice a day, I write an alias for it. If it&apos;s a sequence of commands, I write a script for it. Here&apos;s my reasoning, let&apos;s say with all my tools and scripts I save myself 10 minutes a day. Here&apos;s the math:&lt;/p&gt;
&lt;p&gt;10 Minutes a day * 5 days = 50 minutes a week (big deal, that&apos;s a lunch break)&lt;br /&gt;
50 Minutes a week * 52 weeks/year = 2600 minutes (getting more interesting)&lt;br /&gt;
2600 minutes / 60 minutes (1 hour) = 43.33 hours (Yeah, I just gained a weeks worth of work time for the year)&lt;/p&gt;
&lt;p&gt;You might be thinking, big deal, but what if you are a company of 100 developers and your all paid ~$40/hour&lt;br /&gt;
Total company &apos;savings&apos;: $160,000/year&lt;/p&gt;
&lt;p&gt;You&apos;ll notice that &lt;em&gt;savings&lt;/em&gt; is in quotes. It&apos;s not that you aren&apos;t spending the salary of the developers, they are just getting more time to do their job, so it&apos;s &lt;em&gt;like&lt;/em&gt; saving it, when in reality it&apos;s getting more out of the money you are spending.&lt;/p&gt;
&lt;h3&gt;What&apos;s your secret?&lt;/h3&gt;
&lt;p&gt;So how are you making yourself more efficient? I&apos;d love to hear what tools, workflows, and time saving tips you all have that are helping you get the most out of your precious minutes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1] http://en.wikipedia.org/wiki/United_Parcel_Service&lt;/li&gt;
&lt;li&gt;[2] http://www.eia.gov/dnav/pet/hist/LeafHandler.ashx?f=W&amp;amp;n=PET&amp;amp;s=EMM_EPMR_PTE_NUS_DPG&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>I was part of a social experiment</title><link>https://chrisk.io/posts/part-social-experiment/</link><guid isPermaLink="true">https://chrisk.io/posts/part-social-experiment/</guid><description>Back in June, I was informed I was part of a social experiment. Topher DeRosia of X-Team sent me a tweet, that simply stated:…</description><pubDate>Sat, 16 Aug 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Back in June, I was informed I was part of a social experiment. Topher DeRosia of X-Team sent me a tweet, that simply stated:&lt;/p&gt;
&lt;p&gt;https://twitter.com/topher1kenobe/status/482244842450202625&lt;/p&gt;
&lt;p&gt;I was very intrigued by this, and when I questioned it, he said I was the only one in it. This lead to more intrigue. Over the next few months, Topher and I had many conversations on Twitter, surrounding WordPress, Geek Culture, and just downright fun topics. He&apos;s an organizer of WordCamp Grand Rapids, which I just wrapped up speaking at. During foundation day we ended up at lunch together, sitting directly across from each other. It wasn&apos;t until that day, on August 15th, nearly 6 weeks later, he told me what &quot;experiment&quot; I was a part of.&lt;/p&gt;
&lt;p&gt;Simply put, he wanted to grow connections in the community, by picking one person on Twitter, following them, and focusing on getting to know them by interacting, reading, and including them in conversations. I was blown away. Without knowing it, someone I had really gotten to know over the last 6 weeks, had planned it. In no truer words, I was honored he choose me to start that.&lt;/p&gt;
&lt;p&gt;After lunch, the remaining Friday, speaker dinner, and drive home, I thought about this new relationship we&apos;ve built and want to take part in it. So here&apos;s my plan...&lt;/p&gt;
&lt;p&gt;Starting Today, I&apos;m going to create a Twitter list, and each month put a single person in it. I could just follow them, but by putting them in a list, it gives me a great outlet to see all of their content, without the distractions of my regular timeline. I&apos;m going to do this for the next 6 months, each month swapping out the 1 follower for a different one. My goal will be to interact with that person for the month (and hopefully after) to grow the connections we build as a WordPress community.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/photos/jasonahowie/7910370882/in/photolist-8onC9R-br5x86-e5wZ3t-8d9dGt-9gXesF-6tXvwF-e1HpQq-d41HES-8az8WH-7ew6Zc-e1yRKg-aFyhaH-btpW68-e4CDj3-e5CAgW-8KkoYZ-epHEE2-99Wjs1-czBUG9-5XNfPs-dUmKE4-amC4jN-6mYWTq-aFy3bt-dZxNRq-6u2DBs-5XJ1Qc-9eVCSc-99BVQZ-9MoWtb-9hNywz-9x7H6Z-8bspY4-4oUWXS-6DtPYC-6u2Dkq-7rY7do-6tXvgR-6qPE85-7YNkeA-7YNkh5-8Q7LKc-8Q7LSH-8Q7LZ4-8QaSeA-9yMPBV-71ZNv4-8NyVNa-yv3t2-axnKy3&quot;&gt;Image&lt;/a&gt; used under creative commons - By &lt;a href=&quot;https://www.flickr.com/photos/jasonahowie/&quot;&gt;Jason A Howie&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Leading By Example</title><link>https://chrisk.io/posts/leading-example/</link><guid isPermaLink="true">https://chrisk.io/posts/leading-example/</guid><description>I&apos;ve previously written a few posts about using WordPress Actions and Filters to better extend your plugins and/or themes. This time though, I want to talk…</description><pubDate>Fri, 15 Aug 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve previously written a few posts about using WordPress Actions and Filters to better extend your plugins and/or themes. This time though, I want to talk about leading by example, and using your own hooks and filters to add functionality. What does this mean? It means where a hook or filter exists, you should use it to add your built in functionality. It&apos;s probably easiest to explain by example...so here is a recent issue I ran into. I wanted the ability to create an arbitrary number of &apos;tab&apos; sections in a plugin settings page I was building. Something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2014-08-15-at-3.16.04-PM-1024x141.png&quot; alt=&quot;Screen Shot 2014-08-15 at 3.16.04 PM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now, hard coding a list of tabs is easy, but what if I didn&apos;t want to always show the tabs, just the ones that were active? Well, I could simply make the action of outputting the tabs, an filter that get&apos;s looped on. Like this:&lt;/p&gt;
&lt;p&gt;[php light=true]&lt;br /&gt;
function ck_generate_tabs() {&lt;br /&gt;
$tabs = apply_filters( &apos;ck_metabox_tabs&apos;, array() );&lt;br /&gt;
foreach ( $tabs as $key =&amp;gt; $values ) {&lt;br /&gt;
?&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%3C?php%20echo%20$key;%20?%3E&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$i++;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
[/php]&lt;/p&gt;
&lt;p&gt;If we go no further, we&apos;ll have an empty set, and nothing will foreach on, however, if we do something like the following, we&apos;ll add an element to the array, therefore allowing a loop and generating tabs:&lt;/p&gt;
&lt;p&gt;[php light=true]&lt;br /&gt;
function ck_tw_add_meta_tab( $tabs ) {&lt;br /&gt;
$tabs[&apos;tw&apos;] = array( &apos;name&apos; =&amp;gt; __( &apos;Twitter&apos;, &apos;ppp-txt&apos; ) );&lt;/p&gt;
&lt;p&gt;return $tabs;&lt;br /&gt;
}&lt;br /&gt;
add_filter( &apos;ck_metabox_tabs&apos;, &apos;ck_tw_add_meta_tab&apos;, 10, 1 );&lt;br /&gt;
[/php]&lt;/p&gt;
&lt;p&gt;This is great for 2 reasons.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It makes sure our hooks and filters work!&lt;br /&gt;
I can&apos;t tell you how important this is. By using it, we&apos;ve essentially tested it works as expected, which will make other developers happy.&lt;/li&gt;
&lt;li&gt;It provides other developers a &apos;guide&apos; on how to extend your platform.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The chain we end up with is, you call &lt;code&gt;ck_generate_tabs&lt;/code&gt; which will then run the &lt;code&gt;apply_filters&lt;/code&gt; on &lt;code&gt;ck_metabox_tabs&lt;/code&gt;, which then triggers &lt;code&gt;ck_tw_add_meta_tab&lt;/code&gt; to add an item to the empty array and then return it, allowing the original function to generate the tabs.&lt;/p&gt;
&lt;p&gt;This example is clearly missing styles and JavaScript to allow this to fully function, but this should get you an example of how hooks and filters in your own code, that you, yourself are using.&lt;/p&gt;
</content:encoded></item><item><title>Showing EDD File Download Sizes</title><link>https://chrisk.io/posts/showing-edd-file-download-sizes/</link><guid isPermaLink="true">https://chrisk.io/posts/showing-edd-file-download-sizes/</guid><description>The other day I got an interesting support thread for Easy Digital Downloads, asking for the list of files, and their sizes be displayed when viewing a…</description><pubDate>Fri, 18 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The other day I got an interesting support thread for Easy Digital Downloads, asking for the list of files, and their sizes be displayed when viewing a product. Being that I only use it to sell WordPress plugins, it seemed pretty minor, but if you were dealing with larger Audio/Video files, or your consumers used their mobile devices frequently, I could see how this would be useful. So I put together a quick, single file, plugin that is &lt;a href=&quot;https://github.com/easydigitaldownloads/library/blob/master/downloads/download-file-sizes.php&quot;&gt;now available in the EDD Library Repo on Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, here&apos;s the primary function that is run:&lt;/p&gt;
&lt;p&gt;function edd_ck_show_file_sizes( $post_id ) {
$files = edd_get_download_files( $post_id, null );
$decimals = 2;
$sz = &apos;BKMGTP&apos;;
$header = _n( &apos;File Size&apos;, &apos;File Sizes&apos;, count( $files ), &apos;edd&apos; );
echo &apos;&amp;lt;h5&amp;gt;&apos; . $header . &apos;&amp;lt;/h5&amp;gt;&apos;;
echo &apos;&amp;lt;ul&amp;gt;&apos;;
foreach( $files as $file ) {
$bytes = filesize( get_attached_file( $file[&apos;attachment_id&apos;] ) );
$factor = floor((strlen($bytes) - 1) / 3);
echo &apos;&amp;lt;li&amp;gt;&apos; . $file[&apos;name&apos;] . &apos; - &apos; . sprintf( &quot;%.{$decimals}f&quot;, $bytes / pow( 1024, $factor) ) . @$sz[$factor] . &apos;&amp;lt;/li&amp;gt;&apos;;
}
echo &apos;&amp;lt;/ul&amp;gt;&apos;;
}
add_action( &apos;edd_after_download_content&apos;, &apos;edd_ck_show_file_sizes&apos;, 10, 1 );&lt;/p&gt;
&lt;p&gt;Now, a quick overview. Basically what we&apos;re doing is looking for all the uploaded media items attached as &apos;Downloads&apos; to this product. Once we get them, we&apos;re iterating through them. You see this in the line&lt;/p&gt;
&lt;p&gt;$files = edd_get_download_files( $post_id, null );&lt;/p&gt;
&lt;p&gt;After that we do some setup, only wanting 2 decimal places, setting up the title of the list (following the numeric localization method), and you&apos;ll notice that odd variable &lt;code&gt;BKMGTP&lt;/code&gt;. What is this? Well it&apos;s used to make the output of the size calculation human readable. It&apos;s for &quot;Bytes, Kilobytes, Megabytes, Gigabytes, Terabytes, and Petabytes&quot;. I&apos;ve never seen a use case of someone selling Tera/Petabyte files on EDD, but who am I to judge.&lt;/p&gt;
&lt;p&gt;After that, a little loop to run each calculation by powers of 1024, and we&apos;re good to go!&lt;/p&gt;
&lt;p&gt;You can go &lt;a href=&quot;https://raw.githubusercontent.com/easydigitaldownloads/library/master/downloads/download-file-sizes.php&quot;&gt;grab the full plugin-ready file here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/photos/trainor/1229138273/in/photolist-2SBDZc-4prL9g-6jdsvY-6jBtmv-gnarGS-5wX2Bs-qyMKq-aJE3c4-5Vijca-dkDirG-6je3r7-6cAVab-ftF9z-8BAcDm-gmZkLc-ao2o2q-4vKZr7-4crN2W-5Sp3Qg-bZhC4N-i9VVxB-7AiCZ7-cmbQkm-cktRVf-cmc2QJ-cmegkj-cmaGvb-cmd85N-cktFgy-cktQSL-cma5Z1-cktY7A-cmc7fY-cktJff-cmav11-cktCed-cmaP5f-cmehjf-cmdsNd-cmeio5-cktu9q-cmcNaj-cmcMrL-cmbwNJ-cmbrFo-cmdbcC-cmbxSu-cmaHTw--cktyDh&quot;&gt;Image&lt;/a&gt; credit(CC): &lt;a href=&quot;https://www.flickr.com/photos/trainor/&quot;&gt;John Trainor&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Generating Star Ratings with Dashicons</title><link>https://chrisk.io/posts/generating-star-ratings-dashicons/</link><guid isPermaLink="true">https://chrisk.io/posts/generating-star-ratings-dashicons/</guid><description>Recently I was working on a ratings website, and needed a quick way to consistently generate the current star ratings of the items. Many of you are familiar…</description><pubDate>Mon, 07 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently I was working on a ratings website, and needed a quick way to consistently generate the current star ratings of the items. Many of you are familiar with the &apos;dashicons&apos; font that is shipped with WordPress, but if you aren&apos;t, it&apos;s a simple icon-font available to theme and plugin developers. You&apos;re probably more familiar with it than you think, it&apos;s used to add icons to the WordPress admin dashboard menu:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/Screen-Shot-2014-07-07-at-12.27.33-AM-174x300.png&quot; alt=&quot;Screen Shot 2014-07-07 at 12.27.33 AM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;There are 3 icons I was interested in, and they are the 3 stars:&lt;br /&gt;
&lt;img src=&quot;/images/blog/Screen-Shot-2014-07-07-at-12.41.41-AM-300x86.png&quot; alt=&quot;Screen Shot 2014-07-07 at 12.41.41 AM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;With those icons, I could generate something that looked like this:&lt;br /&gt;
&lt;img src=&quot;/images/blog/Screen-Shot-2014-07-07-at-12.34.11-AM.png&quot; alt=&quot;Screen Shot 2014-07-07 at 12.34.11 AM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This function allows accuracy to the closest 1/2 star. You simply pass in your rating number, and it will return you HTML output for the stars.&lt;/p&gt;
&lt;p&gt;function kfg_generate_stars( $number ) {
// Get the whole number
$whole = floor( $number );&lt;/p&gt;
&lt;p&gt;// Find out if our number contains a decimal&lt;br /&gt;
$fraction = $number - $whole;&lt;/p&gt;
&lt;p&gt;$i = 0;&lt;br /&gt;
// This is the total number of stars to generate.&lt;br /&gt;
$total = 5;&lt;br /&gt;
$output = &apos;&apos;;&lt;/p&gt;
&lt;p&gt;// Generate the filled stars&lt;br /&gt;
while( $i &amp;lt; $whole ) {&lt;br /&gt;
$output .= &apos;&amp;lt;span class=&quot;ratings dashicons dashicons-star-filled&quot;&amp;gt;&amp;lt;/span&amp;gt;&apos;;&lt;br /&gt;
$i++;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;// Generate the half star, if needed&lt;br /&gt;
if ( $fraction &amp;gt; 0 ) {&lt;br /&gt;
$output .= &apos;&amp;lt;span class=&quot;ratings dashicons dashicons-star-half&quot;&amp;gt;&amp;lt;/span&amp;gt;&apos;;&lt;br /&gt;
$i++;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;// Until total is met, generate empty stars&lt;br /&gt;
if ( $i &amp;lt; $total ) {&lt;br /&gt;
while ( $i &amp;lt; $total ) {&lt;br /&gt;
$output .= &apos;&amp;lt;span class=&quot;ratings dashicons dashicons-star-empty&quot;&amp;gt;&amp;lt;/span&amp;gt;&apos;;&lt;br /&gt;
$i++;&lt;br /&gt;
}&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;return $output;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;As a note, if your theme doesn&apos;t include dashicons in the front end (by default it&apos;s only in the Admin), you can use the following to add it:&lt;/p&gt;
&lt;p&gt;function kfg_load_dashicons() {
wp_enqueue_style( &apos;dashicons&apos; );
}
add_action( &apos;wp_enqueue_scripts&apos;, &apos;kfg_load_dashicons&apos; );&lt;/p&gt;
&lt;p&gt;To get a full listing of items included in the Dashicons font, visit &lt;a href=&quot;http://melchoyce.github.io/dashicons/&quot;&gt;http://melchoyce.github.io/dashicons/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Image courtesy of &lt;a href=&quot;https://www.flickr.com/photos/scott-s_photos/&quot;&gt;Scott Cresswell via Flickr&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Your biggest asset as a developer</title><link>https://chrisk.io/posts/biggest-asset-developer/</link><guid isPermaLink="true">https://chrisk.io/posts/biggest-asset-developer/</guid><description>It&apos;s tossed around on resumés, touted as why someone should be paid more, and used to taunt our prowess in the ever so changing world of software…</description><pubDate>Tue, 27 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s tossed around on resumés, touted as why someone should be paid more, and used to taunt our prowess in the ever so changing world of software development. People with 18 years of JavaScript &lt;em&gt;(but it was Mocha back then)&lt;/em&gt; experience, people who remember writing COBOL, and those who hang on to assembly as their crowning jewel of achievement in their development toolbox. Don&apos;t get me wrong, all these languages and accolades hold their place in something each person should be proud of. If these people are &lt;em&gt;&lt;strong&gt;still&lt;/strong&gt;&lt;/em&gt; software developers though, the one thing they should be touting is, &lt;strong&gt;their ability to adapt&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Over time the languages, theories, practices, and tools of the software development trade change. One thing, however, remains the same: Change, and your ability to accept it. If you don&apos;t, you become irrelevant and loose value. I was recently reminded of this by someone with FAR more development experience than I. Someone who can even add sections of the Windows 8 experience to his list of achievements. Even if you don&apos;t like Windows 8 from a functional aspect, you can respect the level of software development it takes to write an operating system. The point is, unless you shift your point of view to see the larger picture, instead of your local problems, you&apos;ll quickly loose ground in your career.&lt;/p&gt;
&lt;p&gt;You might have read a previous post about how a project I was working on, was moving away from WordPress. I &lt;a href=&quot;https://chrisk.io/2014/03/chance-learn-something-new/&quot;&gt;outline my concerns and excitement to try something new&lt;/a&gt;. I was waist deep in that project, and the one thing that I&apos;ve realized is you have to Learn to Learn.&lt;/p&gt;
&lt;h4&gt;Did he just say &quot;Learn to Learn&quot;?&lt;/h4&gt;
&lt;p&gt;Yeah, learning to learn sounds dumb, I know. You&apos;d be surprised how many people can&apos;t seem to grasp new concepts. For some it&apos;s even manifested as a &apos;fanboy/girl&apos; type rivalry where their method/language is better. Don&apos;t believe me? Walk into a room with a diverse group of developers and bring up the topic of data types and casting. It&apos;ll be like an debate grenade went off. People stick to what they know, and when it&apos;s challenged they get defensive. But you don&apos;t have to! Take any opportunity you have to learn about how a language or process works. Things like that help you evolve your skill set and become valuable no matter what team you are on.&lt;/p&gt;
&lt;h4&gt;It&apos;s a life-long education&lt;/h4&gt;
&lt;p&gt;When it all comes down to it, whether you work for yourself or a company, your education and improvement is on you. Let me rephrase that so you hear it better:&lt;br /&gt;
&lt;strong&gt;You alone are responsible for your education&lt;/strong&gt;&lt;br /&gt;
Not your boss, or HR department. Not your professor or teachers. &lt;strong&gt;You, and you alone&lt;/strong&gt; are the one who needs to make the decision to further yourself. The field of software development is one that changes constantly, and rapidly. For instance, about every 6 months, a new version of PHP is released. Some of those minor, but some with great impact to the way we develop. Even if it doesn&apos;t change the way you develop your software, it&apos;s up to you be sure of that.&lt;/p&gt;
&lt;h4&gt;Where do you learn to learn?&lt;/h4&gt;
&lt;p&gt;Learning to learn may seem like a foreign concept, but really what it means is, exercising your brain to retain knowledge. In reality, the only way to do this, is practice. In this case, that means being sure to continue learning and educating yourself.&lt;/p&gt;
&lt;p&gt;This answer is about as personalized as what&apos;s your favorite color. Personally I learn best from doing. I look for tutorials, code snippets, and projects to execute them in. When using tutorials, be sure to write out the lines by hand, and not copy &amp;amp; paste. When you take the time to write out the code, you&apos;re brain processes it differently than just reading.&lt;/p&gt;
&lt;p&gt;Others I know are great book learners. They can pick up a book and become a topic expert in a weekend. This isn&apos;t me. I don&apos;t have the attention span, but if you do, try and read a book a month that pertains to your goals.&lt;/p&gt;
&lt;p&gt;If you are a classroom learner, you can check out your local colleges and see if they have an Audit program. Auditing a class is like taking it, without the grade. You participate in class discussions, get the notes, lectures, and assignments, all with the understanding you are bettering yourself. You&apos;ll have to check with each individual institution to see if they offer this sort of program and if the courses you want to take are available to audit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;So what&apos;s your preferred learning method? Have you taken the time to learn something new lately? What was it?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>Why Your Next BIG Idea Should start small</title><link>https://chrisk.io/posts/next-big-idea-small/</link><guid isPermaLink="true">https://chrisk.io/posts/next-big-idea-small/</guid><description>In the business of start-ups, entrepreneurship, and software development everyone seems to have a single goal. Find the one BIG idea that will become their…</description><pubDate>Mon, 26 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the business of start-ups, entrepreneurship, and software development everyone seems to have a single goal. Find the one BIG idea that will become their successful business model. There&apos;s only one problem with this mentality.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Big Ideas are hard!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&apos;m not just talking about the requirements for big ideas either. Large projects are hard to start, hard to scope, hard to complete on time, and hard to maintain. All because of one thing...they are BIG. More complexity means more ways to &apos;break&apos; the project. Scope changes mean missed deadlines. And large code bases mean increased maintenance costs. Of course these are generalizations, not everyone will run into these hurdles, but you should expect to.&lt;/p&gt;
&lt;p&gt;So how do you start a big idea, small? You iterate. Both of my major projects I&apos;m working on started this way. A single idea that I (or a friend had). It wasn&apos;t a huge conversation. They both started with, what is probably, almost the same exact statement: &lt;em&gt;&quot;There has to be a better way to do _______&quot;&lt;/em&gt;&lt;/p&gt;
&lt;h5&gt;Where to Start&lt;/h5&gt;
&lt;p&gt;I&apos;ve always found it easiest to start with a small problem that scratches your own itch. Something that solves your own problem. For me Pushover Notifications for WordPress came about because I don&apos;t like email notifications. I like short, concise notifications that get right to the point. I built something that achieved this. All notifications for Pushover are 150 characters or less. It also keeps my email inbox cleaner.&lt;/p&gt;
&lt;p&gt;Chris Lema posted a short while ago about about &quot;&lt;a href=&quot;http://chrislema.com/dont-scratch-your-itch/&quot;&gt;NOT Scratching Your Own Itch&lt;/a&gt;&quot;, and his arguments are completely valid. I think though, that you can scratch an itch, while being completely aware of his concerns. You should read his post though, so you can be aware of the issues you may face. If there is one thing he has, it&apos;s experience.&lt;/p&gt;
&lt;h5&gt;What next?&lt;/h5&gt;
&lt;p&gt;After releasing your small project, there will be a time where feature requests and bugs alike roll in. This is where you start turning the small little niche idea, into a larger thing. One driven by user feedback. My most recent plugin, &lt;a href=&quot;https://chrisk.io/ppp&quot;&gt;Post Promoter Pro&lt;/a&gt;, is being updated to version 1.3 soon, and it&apos;s consisting of 6 features, 5 suggested by users who purchased on day one.&lt;/p&gt;
&lt;p&gt;So am I suggesting you use your customers as beta testers? By no means at all. What I&apos;m suggesting is that as you develop your product, allow the customer&apos;s to drive some of it&apos;s direction. Not only will you get further than you can on your own, but they&apos;ll feel a sense of ownership in the product. Thus, turning your &apos;small idea&apos; into a flourishing consumer product.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;What methods do you use to start projects? Do you believe in a completed idea or a minimum viable product (MVP)?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>Don&apos;t Pitch Me Bro!</title><link>https://chrisk.io/posts/dont-pitch-bro/</link><guid isPermaLink="true">https://chrisk.io/posts/dont-pitch-bro/</guid><description>Ask most sales/marketing people and they&apos;ll tell you, pitches are a numbers game. The more people you offer to, the more sales you&apos;ll get. They aren&apos;t…</description><pubDate>Sun, 18 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ask most sales/marketing people and they&apos;ll tell you, pitches are a numbers game. The more people you offer to, the more sales you&apos;ll get. They aren&apos;t wrong, it&apos;s a statistical fact. If you ask more people, you&apos;ll eventually get more sales. Let me be the first to say, I hate this strategy. It&apos;s inefficient.&lt;/p&gt;
&lt;h4&gt;I&apos;m not your target audience&lt;/h4&gt;
&lt;p&gt;The other day I was walking through a supermarket to grab one thing, and one thing only. I knew where it was, took the most direct route, and still got caught by a pitch. DirecTV happened to be there trying to sign people up. Now, some of you might know, my family has been without Cable (or Satellite) for almost a year and a half now. The conversation went something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sales Guy: Hi sir, who do you currently have for cable? Me: No one actually. SG: (With a surge of enthusiasm in his eyes) Really?! (Thinking it was an easy sell) Me: Yep, we cut DirecTV almost a year and a half ago. SG: (Extremely surprised) Seriously?! Why? Me: Yep, we just didn&apos;t use it enough. Felt it wasn&apos;t worth the cost. SG: What if it was $20? (Thinking he had me...who can resist $20/mo) Me: Are you guys with that new &quot;Prism&quot; system? SG: No, DirecTV actually... Me: Ah. Ok. Nope, we&apos;re good actually thank you. SG: Ok, have a great day!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;First of all, I respect this young kid for the one thing most sales people don&apos;t ever catch...&lt;strong&gt;&lt;em&gt;Not everyone is your target audience&lt;/em&gt;&lt;/strong&gt;. Some would say he should have pitched harder. That he could have had me. The truth is, he&apos;d never have me. I don&apos;t want his product, and he was able to tell that from our short conversation. He knew to let me go. There were plenty of other people just behind me.&lt;/p&gt;
&lt;h4&gt;Don&apos;t be hurt or discouraged&lt;/h4&gt;
&lt;p&gt;If someone simply doesn&apos;t want what you are selling, that&apos;s fine. They may just actually not want it. At the end of the day, your time is money, and the quicker you can spot a mark that 100% is not interested, the more money you save. Stop investing time, energy (and money) in the people who won&apos;t ever convert, and start focusing on the people who you can identify will.&lt;/p&gt;
&lt;h4&gt;I&apos;m really not trying to tell you not to pitch&lt;/h4&gt;
&lt;p&gt;Seriously. I&apos;m not. Just be smarter about your pitch. Let me tell you a cliche fishing story that totally relates to this idea of &quot;catching the big one&quot; (I have proof too).&lt;/p&gt;
&lt;p&gt;Last October I was down in Florida on family vacation and went charter fishing. We weren&apos;t looking for anything huge, just some red snappers and Redfish. All day we were pulling them in, but one of them I had was different. This thing &lt;em&gt;FAUGHT&lt;/em&gt;. It ran, and would dive, and run and run and dive...but eventually when it got closer to the top, we saw it...a really nice size Barracuda. Have you ever seen one of these? Ok, take a look at this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/barracuda-teeth-close-up-300x231.jpg&quot; alt=&quot;barracuda-teeth-close-up&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Yes, those teeth can cut a line in a heartbeat, and they usually do. I was told they actually hunt by just swimming with their mouth open and running into their prey...and slice them up. Scary stuff. Anyway, back to the story...there&apos;s no way I should have ever caught this fish on this line. No metal leader, not the right bait. That day though, this particular fish decided it was time. And here we are.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you don&apos;t ever throw the line overboard, you never know what you&apos;ll catch.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh, and the proof:&lt;br /&gt;
&lt;img src=&quot;/images/blog/20131016_101047-168x300.jpg&quot; alt=&quot;20131016101047&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;What kind of salesperson are you? Can you identify, and respectfully turn away, someone who clearly isn&apos;t interested? Or do you keep pursuing?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Editorial Note/Promotion: If you are ever in Tampa, Florida and looking to do some charter fishing, &lt;a href=&quot;http://www.bassnbaycharters.com/joomla/&quot;&gt;I HIGHLY recommend Capt. Brady Nelson of Bass N&apos; Bay Charters&lt;/a&gt;. No paid promotion, just straight up happy customer. Great Guy.&lt;/p&gt;
</content:encoded></item><item><title>A List of EDD Contributors</title><link>https://chrisk.io/posts/list-edd-contributors/</link><guid isPermaLink="true">https://chrisk.io/posts/list-edd-contributors/</guid><description>So .club domains released today, and I decided to grab edd.club to help quickly showcase some of the top contributors on Easy Digital Downloads. Not sure…</description><pubDate>Wed, 07 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So .club domains released today, and I decided to grab &lt;a href=&quot;http://edd.club&quot;&gt;edd.club&lt;/a&gt; to help quickly showcase some of the top contributors on Easy Digital Downloads. Not sure where else I&apos;ll go with it, but we&apos;ll see.&lt;/p&gt;
</content:encoded></item><item><title>Developer ProTip: Don&apos;t be tricky</title><link>https://chrisk.io/posts/developer-protip-dont-tricky/</link><guid isPermaLink="true">https://chrisk.io/posts/developer-protip-dont-tricky/</guid><description>Well that was embarrassing! Day 1 of a plugin release. One of my first customers. Boom, Fatal Error. (╯°□°）╯︵ ┻━┻ In short, it was a simple mistake on my…</description><pubDate>Mon, 05 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Well that was embarrassing! Day 1 of a plugin release. One of my first customers. Boom, Fatal Error. (╯°□°）╯︵ ┻━┻&lt;/p&gt;
&lt;p&gt;In short, it was a simple mistake on my part, by using a function in PHP that wasn&apos;t supported by versions of PHP lower the 5.3. Now, some of your purist developers and site owners might think &quot;Well, that&apos;s their fault for not having a modern version of PHP&quot;. Let me remind you, &lt;a href=&quot;http://wordpress.org/about/requirements/&quot;&gt;WordPress still requires PHP 5.2.4 or greater&lt;/a&gt;. I write WordPress plugins, therefore I must support PHP 5.2.4 or greater. I&apos;ll take full responsibility for that.&lt;/p&gt;
&lt;p&gt;So what did I do wrong? Well, PHP 5.3 introduced &apos;closures&apos;, or what other languages call &quot;Anonymous Functions&quot;. The line of code in question was this:&lt;/p&gt;
&lt;p&gt;$utm_string .= implode( &apos;&amp;amp;&apos;, array_map( function ( $v, $k ) { return &apos;utm_&apos; . $k . &apos;=&apos; . $v; }, $utm, array_keys( $utm ) ) );&lt;/p&gt;
&lt;p&gt;To be completely honest, this line of code should have been (and was actually replaced by) a simple foreach loop. So why didn&apos;t I do that? Simple answer is, I was looking for a &apos;fancy&apos; way to make it a one liner. Closures are a powerful tool and can be used very intelligently...if your sure that the version of PHP being used is new enough. In this case, it was just a &apos;tricky&apos; way to make 6 lines into 1. Here&apos;s the replaced code:&lt;/p&gt;
&lt;p&gt;$first = true;
foreach ( $utm as $key =&amp;gt; $value ) {
if ( !$first ) {
$utm_string .= &apos;&amp;amp;&apos;;
}&lt;/p&gt;
&lt;p&gt;$utm_string .= &apos;utm_&apos; . $key . &apos;=&apos; . $value;&lt;br /&gt;
$first = false;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;See, minus whitespace and brackets, 6 lines of code. So stop being tricky developers! just take a few extra minutes to do it the compatible way. You AND your users will thank you later. Still not convinced? Great, here&apos;s a few more reasons why tricky code is a bad idea.&lt;/p&gt;
&lt;h3&gt;1. Tricky code is NOT readable&lt;/h3&gt;
&lt;p&gt;Look at that line I wrote above. Not the nice foreach...but that monstrosity of a single line. That thing is not easy to read. The variables are named poorly. No whitespacing, and it just reads like a compiled mess. We use non-compiled languages for a reason, and it&apos;s so we don&apos;t have to look at crap like that.&lt;/p&gt;
&lt;h3&gt;2. Tricky code is NOT safe&lt;/h3&gt;
&lt;p&gt;Finding a tricky unique way to make a shortcut usually isn&apos;t backwards compatible. Think about it, the tricky way exists in the version you are using, because over time we&apos;ve grown to find a need for a shorter method. Older versions of the platform may not have that ability.&lt;/p&gt;
&lt;h3&gt;3. Tricky code is NOT easily debugged&lt;/h3&gt;
&lt;p&gt;I&apos;ll draw your attention again to Exhibit A. How would you put debug code into that thing? Not easily right? You&apos;d be having to count brackets, and make sure you&apos;re in the right method. Now compare that with the simply foreach loop. We could easily throw a line or two of debugging in there without having to worry about breaking the logic.&lt;/p&gt;
&lt;p&gt;Look, I&apos;m not opposed to using clever methods to do things. That&apos;s what developers do...but when it comes to your customers, just make sure you put their experience before your number of lines of code. I&apos;ll leave you with one quote before I prompt you, and it&apos;s one I love using:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.&lt;br /&gt;
-Brian Kernighan: Co-Developer of Unix&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;So what&apos;s one way you&apos;ve been tricky, and how has it hurt (or helped!) you out?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>My Must Have Books on Software Development</title><link>https://chrisk.io/posts/must-books-software-development/</link><guid isPermaLink="true">https://chrisk.io/posts/must-books-software-development/</guid><description>You can&apos;t be a good software developer without reading. That&apos;s just a straight up fact. Whether it&apos;s blog posts, documentation, or good ole&apos; fashioned…</description><pubDate>Thu, 01 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;You can&apos;t be a good software developer without reading. That&apos;s just a straight up fact. Whether it&apos;s blog posts, documentation, or good ole&apos; fashioned books, you have to keep educating yourself. The most common question I get from newer developers is &quot;Do you have any good books you recommend?&quot;&lt;/p&gt;
&lt;p&gt;This is a pretty difficult topic as each person learns differently, and frankly, most don&apos;t learn from books easily. There is a plethora of writing styles and book formats for software development, but here you go, some books I recommend anyone getting into software development should read.&lt;/p&gt;
&lt;h4&gt;1. &lt;a href=&quot;https://chrisk.io/CleanCode&quot;&gt;Clean Code&lt;/a&gt; (and &lt;a href=&quot;https://chrisk.io/CleanCoder&quot;&gt;The Clean Coder&lt;/a&gt;) - &lt;a href=&quot;http://amazon.com/s/ref=as_li_bk_tl/?url=search-alias%3Daps&amp;amp;field-keywords=Robert%20C.%20Martin&amp;amp;tag=kfg-20&amp;amp;linkId=6fc431b10d07207fcc024c302589541c&amp;amp;linkCode=ktl&quot;&gt;Robert C. Martin&lt;/a&gt;&lt;img src=&quot;https://ir-na.amazon-adsystem.com/e/ir?source=bk&amp;amp;t=kfg-20&amp;amp;bm-id=default&amp;amp;l=ktl&amp;amp;linkId=6fc431b10d07207fcc024c302589541c&amp;amp;_cb=1462525081305&quot; alt=&quot;&quot; /&gt;&lt;/h4&gt;
&lt;p&gt;If you are going to buy one book of this entire list, this is the one I would suggest. It&apos;s written extremely well and has actually changed the way I write code. It&apos;s messages are so cleanly defined and easily understood, that I actually started using it&apos;s best practices subconsciously. In the world of software development books, this to me is required reading.&lt;/p&gt;
&lt;p&gt;It talks about writing code as a craft, not just a hobby or skill. Lines are thoughtfully constructed to be the most efficient and still be readable to passers by. It&apos;s an inspiring look at the smallest tasks like naming conventions all the way up to framework development. The follow up book, &lt;em&gt;&quot;The Clean Coder&quot;&lt;/em&gt; expands on the craft of writing code and goes into how to manage your career as a software developer. Also worth a read.&lt;/p&gt;
&lt;h4&gt;2. &lt;a href=&quot;https://chrisk.io/Pragmatic&quot;&gt;The Pragmatic Programmer&lt;/a&gt; - Andrew Hunt &amp;amp; David Thomas&lt;/h4&gt;
&lt;p&gt;The Pragmatic Programmer is also a language-agnostic book. While Clean Code focuses on the code itself (as the name suggests), this book focuses on the process. Ways to make you the most efficient at what you do. Programmers have a different mindset when it comes to completing tasks, and throughout the book, they urge developers to apply the same logic, efficiency, and rapid itteration through their entire project lifecycle.&lt;/p&gt;
&lt;h4&gt;3. &lt;a href=&quot;https://chrisk.io/BeingGeek&quot;&gt;Being Geek&lt;/a&gt; - &lt;a href=&quot;http://amazon.com/s/ref=as_li_bk_tl/?url=search-alias%3Daps&amp;amp;field-keywords=Michael%20Lopp&amp;amp;tag=kfg-20&amp;amp;linkId=eada09a48b9443853279973fe4625229&amp;amp;linkCode=ktl&quot;&gt;Michael Lopp&lt;/a&gt;&lt;img src=&quot;https://ir-na.amazon-adsystem.com/e/ir?source=bk&amp;amp;t=kfg-20&amp;amp;bm-id=default&amp;amp;l=ktl&amp;amp;linkId=eada09a48b9443853279973fe4625229&amp;amp;_cb=1462525088946&quot; alt=&quot;&quot; /&gt;&lt;/h4&gt;
&lt;p&gt;At the end of the day, the only person looking out for your career in Software Development, is you. Your manager and HR department, while on your side, want to keep you. It&apos;s up to you to evaluate your worth and determine where you are best suited. Being Geek has anecdotal stories throughout the career of the author, ranging from being a developer, up to management, and even back down to developer again. Lopp shares these stories in a way that is almost like entertainment, and you&apos;ll almost forget you are learning how to manage your career.&lt;/p&gt;
&lt;h4&gt;4. &lt;a href=&quot;https://chrisk.io/JoelSoftware&quot;&gt;Joel on Software&lt;/a&gt; - &lt;a href=&quot;http://amazon.com/s/ref=as_li_bk_tl/?url=search-alias%3Daps&amp;amp;field-keywords=Joel%20Spolsky&amp;amp;tag=kfg-20&amp;amp;linkId=f233894325f88150310de12e9cd59a13&amp;amp;linkCode=ktl&quot;&gt;Joel Spolsky&lt;/a&gt;&lt;img src=&quot;https://ir-na.amazon-adsystem.com/e/ir?source=bk&amp;amp;t=kfg-20&amp;amp;bm-id=default&amp;amp;l=ktl&amp;amp;linkId=f233894325f88150310de12e9cd59a13&amp;amp;_cb=1462525096873&quot; alt=&quot;&quot; /&gt;&lt;/h4&gt;
&lt;p&gt;This is a collection of blog posts, formatted as an eBook, containing stories and lessons learned from years in the software development field. Joel started Fog Creek Software, the developers behind one of my favorite task management apps Trello. While I can&apos;t state he covers any one specific topic, this is a great look into the life of developers and the worlds around them.&lt;/p&gt;
&lt;h3&gt;And some domain specific books I recommend&lt;/h3&gt;
&lt;h4&gt;&lt;a href=&quot;https://chrisk.io/ProWordPress&quot;&gt;Professional WordPress Design &amp;amp; Development&lt;/a&gt; - &lt;a href=&quot;https://twitter.com/williamsba&quot;&gt;Brad Williams&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/mirmillo&quot;&gt;David Damstra&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/freeholdhal&quot;&gt;Hal Stern&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;This! This is the must have book if you are writing plugins or themes for WordPress. Be sure to get the 2nd edition, as it&apos;s been updated since the original release.&lt;/p&gt;
&lt;h4&gt;&lt;a href=&quot;https://chrisk.io/JSGood&quot;&gt;Javascript: The Good Parts&lt;/a&gt; - Douglas Crockford&lt;/h4&gt;
&lt;p&gt;If you have development experience, and are not 100% familiar with Javascript, this book is a great &apos;opinion piece&apos; from the author on what the good things in Javascript are. All languages have good and bad, that&apos;s just a fact. The important part is learning the good when you first start, so you can not have bad habits when you start upping your game. At under $10, it&apos;s a quick read and honestly wasn&apos;t super insightful, but was a really good jump start for the language.&lt;/p&gt;
&lt;h3&gt;And there you have it&lt;/h3&gt;
&lt;p&gt;All in total, that&apos;s almost 2500 pages of some of the best writing about being a software developer I know of. I&apos;ve read each of these personally, and while at times reading about writing code can be pretty boring, each of these books offers a different perspective on honing your skills as a craftsperson in this modern day trade.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Clearly there isn&apos;t enough time in the day to read every book out there so, What are your recommended reads on software development?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>Using Easy Digital Downloads Software Licensing as an API GateKeeper</title><link>https://chrisk.io/posts/using-easy-digital-downloads-software-licensing-api-gatekeeper/</link><guid isPermaLink="true">https://chrisk.io/posts/using-easy-digital-downloads-software-licensing-api-gatekeeper/</guid><description>It&apos;s no secret I&apos;m a fan of Easy Digital Downloads as I&apos;m a contributor and support technician Lead Developer for the project. I&apos;m also a HUGE fan of the…</description><pubDate>Sat, 19 Apr 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s no secret I&apos;m a fan of Easy Digital Downloads as I&apos;m a ~contributor and support technician~ Lead Developer for the project. I&apos;m also a HUGE fan of the &lt;a href=&quot;https://chrisk.io/EDDSL&quot;&gt;Software Licensing Extension&lt;/a&gt; we sell for it. While it&apos;s a verify flexible extension, the vast majority of people use it to sell WordPress Plugins and Themes, as it enables users to update the items from within their WordPress admin. I needed to take it a bit further though. During the development of &lt;a href=&quot;https://postpromoterpro.com&quot;&gt;Post Promoter Pro&lt;/a&gt; I found it necessary for the plugin to periodically &quot;call home&quot; (once a week in this case) to postpromoterpro.com to get updated social media tokens and data necessary for proper functionality.&lt;/p&gt;
&lt;p&gt;The key here though, was I didn&apos;t want just anybody to be able to access my API. I wanted any customer with a valid or expired license key to be able to retrieve this data. In your case, you may just want valid, but in my case I found it beneficial to the users to allow this to work after expiration, they just won&apos;t get updates to the plugin itself. So here&apos;s what I did.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is a pretty code heavy example, so I apologize ahead of time&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The following code does require the &lt;a href=&quot;https://chrisk.io/EDDSL&quot;&gt;Software Licensing extension&lt;/a&gt; and &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads&lt;/a&gt; be installed and activated.&lt;/p&gt;
&lt;h3&gt;On our site running EDD Software Licensing&lt;/h3&gt;
&lt;p&gt;We need to create an API endpoint for the plugin to call. Here&apos;s one I built. It receives a license key, and checks it&apos;s status, returning the appropriate data for each case.&lt;/p&gt;
&lt;p&gt;[purchase_link id=&quot;2436&quot; text=&quot;Download as a Plugin&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;/p&gt;
&lt;p&gt;&amp;lt;?php
/*
Plugin Name: EDD SL Endpoint for status
Plugin URI: http://filament-studios.com
Description: Creates and endpoint to get license key status
Version: 1.0
Author: Filament Studios
Author URI: http://filament-studios.com
License: GPLv2
*/&lt;/p&gt;
&lt;p&gt;add_action( &apos;init&apos;, &apos;ck_eddsl_add_endpoint&apos; );&lt;br /&gt;
function ck_eddsl_add_endpoint( $rewrite_rules ) {&lt;br /&gt;
add_rewrite_endpoint( &apos;ck-eddsl-api&apos;, EP_ALL );&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;register_activation_hook( __FILE__, &apos;ck_eddsl_activation_tasks&apos; );&lt;br /&gt;
function ck_eddsl_activation_tasks() {&lt;br /&gt;
flush_rewrite_rules();&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;register_deactivation_hook( __FILE__, &apos;ck_eddsl_deactivation_tasks&apos; );&lt;br /&gt;
function ck_eddsl_deactivation_tasks() {&lt;br /&gt;
flush_rewrite_rules();&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;add_filter( &apos;query_vars&apos;, &apos;ck_eddsl_query_vars&apos; );&lt;br /&gt;
function ck_eddsl_query_vars( $vars ) {&lt;br /&gt;
$vars[] = &apos;ck-eddsl-license-key&apos;;&lt;/p&gt;
&lt;p&gt;return $vars;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;add_action( &apos;template_redirect&apos;, &apos;ck_eddsl_process_request&apos;, -1 );&lt;br /&gt;
function ck_eddsl_process_request() {&lt;br /&gt;
global $wp_query;&lt;/p&gt;
&lt;p&gt;// If our endpoint isn&apos;t hit, just return&lt;br /&gt;
if ( ! isset( $wp_query-&amp;gt;query_vars[&apos;ck-eddsl-api&apos;] ) ) {&lt;br /&gt;
return;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;// If they didn&apos;t supply a key, return&lt;br /&gt;
if ( ! isset( $wp_query-&amp;gt;query_vars[&apos;ck-eddsl-license-key&apos;] ) ) {&lt;br /&gt;
ck_eddsl_output( array( &apos;error&apos; =&amp;gt; &apos;No License Key Provided&apos; ) );&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;$sl = edd_software_licensing();&lt;/p&gt;
&lt;p&gt;define( &apos;EDD_BYPASS_NAME_CHECK&apos;, true );&lt;br /&gt;
$status = $sl-&amp;gt;check_license( array( &apos;key&apos; =&amp;gt; $wp_query-&amp;gt;query_vars[&apos;ck-eddsl-license-key&apos;] ) );&lt;/p&gt;
&lt;p&gt;// If the key isn&apos;t invalid or disabled, return our API data&lt;br /&gt;
if ( $status != &apos;invalid&apos; &amp;amp;&amp;amp; $status != &apos;disabled&apos; ) {&lt;br /&gt;
$data = array( &apos;foo&apos; =&amp;gt; &apos;bar&apos; );&lt;br /&gt;
ck_eddsl_output( $data );&lt;br /&gt;
} else {&lt;br /&gt;
ck_eddsl_output( array( &apos;error&apos; =&amp;gt; &apos;Invalid License Key. Cheetin\&apos; eh?&apos; ) );&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;function ck_eddsl_output( $output ) {&lt;br /&gt;
// Helps us exit any output buffers started by plugins or themes&lt;br /&gt;
$ob_status = ob_get_level();&lt;br /&gt;
while ( $ob_status &amp;gt; 0 ) {&lt;br /&gt;
ob_end_clean();&lt;br /&gt;
$ob_status--;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;// Output the data for the endpoint&lt;br /&gt;
header( &apos;Content-Type: application/json&apos; );&lt;br /&gt;
echo json_encode( $output );&lt;br /&gt;
exit;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;[purchase_link id=&quot;2436&quot; text=&quot;Download as a Plugin&quot; style=&quot;button&quot; color=&quot;green&quot;]&lt;/p&gt;
&lt;p&gt;To test this, just be sure you have a valid license key, and you should be able to send a request like this:&lt;br /&gt;
&lt;code&gt;https://yoursite.com/ck-eddsl-api?ck-eddsl-license-key=[valid license key here]&lt;/code&gt;&lt;br /&gt;
And receive a response like this:&lt;br /&gt;
&lt;code&gt;   {&quot;foo&quot;: &quot;bar&quot;}   &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;NOTE: If your endpoint gives you a 404, just go into your Settings -&amp;gt; Permalinks and click &apos;Save&apos;&lt;/p&gt;
&lt;h3&gt;In the plugin the user installs:&lt;/h3&gt;
&lt;p&gt;We need to create a way for the plugin the user purchases to call home to our site and retrieve the data depending on the status of their license key. In short this function does the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Checks if the transient exists&lt;/li&gt;
&lt;li&gt;Requests the data from the API if it doesn&apos;t&lt;/li&gt;
&lt;li&gt;Stores the data from the API for a week&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;function ck_eddsl_get_api_data() {
$current_data_from_api = get_transient( &apos;my_api_data&apos; );&lt;/p&gt;
&lt;p&gt;if ( !$current_data_from_api ) {&lt;br /&gt;
$license = trim( get_option( &apos;_my_license_key&apos; ) );&lt;br /&gt;
$url = EDDSL_STORE_URL . &apos;/ck-eddsl-api?ck-eddsl-license-key=&apos; . $license;&lt;br /&gt;
$args = array( &apos;timeout&apos; =&amp;gt; 15, &apos;sslverify&apos; =&amp;gt; false );&lt;br /&gt;
$response = wp_remote_get( $url, $args );&lt;/p&gt;
&lt;p&gt;if ( is_wp_error( $response ) ) {&lt;br /&gt;
return false;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;$current_data_from_api = json_decode( wp_remote_retrieve_body( $response ) );&lt;br /&gt;
if ( !isset( $current_data_from_api-&amp;gt;error ) ) {&lt;br /&gt;
set_transient( &apos;my_api_data&apos;, $current_data_from_api, WEEK_IN_SECONDS );&lt;br /&gt;
}&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;// Do something with $current_data_from_api&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;Now, by calling this function &lt;code&gt;ck_eddsl_get_api_data&lt;/code&gt;, the plugin will either retrieve the data from the transient if it exists from a previous call, or go to our API to get it, sending along the user&apos;s license key.&lt;/p&gt;
&lt;h3&gt;Putting it all together&lt;/h3&gt;
&lt;p&gt;Now that we have the plugin, and the endpoint setup. Your user&apos;s sites can request data from you directly, once a week, only if they&apos;ve ever held a valid license key. This could be used in a number of ways, especially in a SaaS implementation. My example here is just one way it could be done.&lt;/p&gt;
</content:encoded></item><item><title>Work vs. Procrastination</title><link>https://chrisk.io/posts/work-vs-procrastination/</link><guid isPermaLink="true">https://chrisk.io/posts/work-vs-procrastination/</guid><description>The work you do while you procrastinate is probably the work you should be doing for the rest of your life. - Jessica Hische (letterer, illustrator, and…</description><pubDate>Fri, 18 Apr 2014 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;The work you do while you procrastinate is probably the work you should be doing for the rest of your life.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;- Jessica Hische (letterer, illustrator, and type designer)&lt;/p&gt;
</content:encoded></item><item><title>A Chance To Learn Something New</title><link>https://chrisk.io/posts/chance-learn-something-new/</link><guid isPermaLink="true">https://chrisk.io/posts/chance-learn-something-new/</guid><description>In my last 4 years as a software developer for GoDaddy, I&apos;ve had the chance to work on one of the largest scale WordPress sites that I&apos;ve ever worked with.…</description><pubDate>Sun, 23 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In my last 4 years as a software developer for GoDaddy, I&apos;ve had the chance to work on one of the largest scale WordPress sites that I&apos;ve ever worked with. Both on a traffic and complexity scale. I&apos;d share numbers but I&apos;m not sure if that&apos;s allowed at this point in time. I&apos;m sure there are larger sites out there, but this was my largest. There were many custom plugins, frameworks, integrations, and modifications that we implemented in order to make WordPress work the way the stakeholder&apos;s wanted. When I joined the team it was a codebase with a large number of core hacks and &apos;bolted on&apos; parts. This wasn&apos;t due to bad developers, just a result of not having WordPress developers. It worked for what was needed and got the job done. When I joined the team, throughout the four years of working on it, we were able to reduce that to 2 core hacks and a LARGE number of plugins and theme features. Due to the improvements my team and I made over the years, we were able to reduce the hardware requirements in half and increase performance to the point that our Database engineers said there were significant drops in load.&lt;/p&gt;
&lt;p&gt;As you can tell, I&apos;m very proud of what my team and I achieved throughout the last 4 years, but as the great philosopher Bob Dylan said, &quot;Times, they are a-changin&apos;&quot;.&lt;/p&gt;
&lt;p&gt;Over the last 4 years, I&apos;ve had 3 stakeholders, all with slightly different views of what our product was. This resulted in some technical debt while shifting gears on short timeframes. The latest of these changes left us looking at the overall requirements, and realized that WordPress wasn&apos;t necessary for the future of the product, so we&apos;re starting to re-architecture and redesign the codebase. Some developers might take offense to this and feel that it&apos;s calling their previous worthless, but I choose to take the perspective that it&apos;s an opportunity to take my expert knowledge in the current codebase, and translated it into something new.&lt;/p&gt;
&lt;p&gt;Not only is the app shifting away from WordPress, but PHP entirely. We&apos;re moving to a NodeJS stack with ElasticSearch for a data source. A HUGE change in direction for me, who&apos;s focused on WordPress, PHP, and MySQL. Am I afraid? You bet. Is it frustrating at times? Sure. But what I&apos;ve learned in the last 4 years is that any good developer can adapt to the world around them. If it means learning a new language, technology, or technique...going with the change and educating yourself is a much easier resisting it the entire way. Even if it hurts to see your old code get retired, you can use the knowledge gained from it to make the new iteration better.&lt;/p&gt;
&lt;h5&gt;What does this mean for my job&lt;/h5&gt;
&lt;p&gt;Nothing. I&apos;m still a software developer at GoDaddy. I&apos;m even still on the same team. My team is just being tasked with updating the architecture and codebase to one more suitable for the project&apos;s scope.&lt;/p&gt;
&lt;h5&gt;So what does all this mean for my current WordPress plugins?&lt;/h5&gt;
&lt;p&gt;Not a thing. I&apos;m still a WordPress developer in my free time. This change only affects the job I do at work. It may however improve my JavaScript in my personal projects. If you follow me on Twitter or Google+, it might mean you&apos;ll see a few more things related to Node or ElasticSearch in addition to my WordPress posts.&lt;/p&gt;
&lt;p&gt;Overall, I&apos;m really excited to take this project to a new level and see what I can achieve.&lt;/p&gt;
</content:encoded></item><item><title>Pushover Notifications for Completed Transmission Downloads</title><link>https://chrisk.io/posts/pushover-notifications-completed-transmission-downloads/</link><guid isPermaLink="true">https://chrisk.io/posts/pushover-notifications-completed-transmission-downloads/</guid><description>Although widely used for piracy, Torrents have their place in the legit world too. I use them quite often to download larger Linux distributions as well as…</description><pubDate>Thu, 13 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Although widely used for piracy, Torrents have their place in the legit world too. I use them quite often to download larger Linux distributions as well as other large open source projects. Sometimes these will take an hour or two to complete...but I want to know when it&apos;s done without leaving the sound on my desktop turned up to 11 (or 12, or 30). So I set out to use some Bash scripts, daemons, and &lt;a href=&quot;https://chrisk.io/pushover&quot;&gt;Pushover&lt;/a&gt; to complete this task.&lt;/p&gt;
&lt;h3&gt;What you&apos;ll need&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Linux Operating System (Not sure how to do this with Windows but OS X should be fairly similar)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://transmissionbt.com&quot;&gt;Transmission&lt;/a&gt; Torrent Client&lt;/li&gt;
&lt;li&gt;Pushover Mobile App (&lt;a href=&quot;https://chrisk.io/pushover&quot;&gt;iOS&lt;/a&gt; / &lt;a href=&quot;https://wp-push.com/GetPushoverAndroid&quot;&gt;Android&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Create a Pushover Application&lt;/h3&gt;
&lt;p&gt;First you&apos;ll need an application in your Pushover account to bridge Transmission with the &lt;a href=&quot;https://chrisk.io/pushover&quot;&gt;Pushover Mobile app&lt;/a&gt;. Visit https://pushover.net/apps/build and name this app whatever you like. Here&apos;s what mine looks like:&lt;br /&gt;
&lt;a href=&quot;/images/blog/Pushover-Edit-Application.png&quot;&gt;&lt;img src=&quot;/images/blog/Pushover-Edit-Application-1024x608.png&quot; alt=&quot;Setup a Pushover Application&quot; /&gt;&lt;/a&gt; Setup a Pushover Application&lt;/p&gt;
&lt;p&gt;Be sure to note the &quot;API Token/Key&quot; and your &quot;User Key&quot; (available when you first login to Pushover.net), a we&apos;ll need those in a moment.&lt;/p&gt;
&lt;h3&gt;Next up, the Script&lt;/h3&gt;
&lt;p&gt;The script is pretty small, but is what connects Transmission to your Pushover App that we just created. Here&apos;s the script, and then I&apos;ll explain a little:&lt;/p&gt;
&lt;p&gt;#!/bin/sh
/var/lib/transmission-daemon/info
curl -k https://api.pushover.net/1/messages.json -F token=[API Token/Key from above] -F user=[Pushover User Key] -F title=&quot;Download Complete&quot; -F message=&quot;$TR_TORRENT_NAME completed&quot;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/var/lib/transmission-daemon/info&lt;/code&gt;&lt;br /&gt;
This line loads up some basic information for us about the download that completed. It&apos;s what allows us to use &lt;code&gt;$TR_TORRENT_NAME&lt;/code&gt; to get the name of the torrent.&lt;/p&gt;
&lt;p&gt;That big ole&apos; &lt;code&gt;curl&lt;/code&gt; command calls to the Pushover API and passes in our application token, user key, a title, and a message.&lt;/p&gt;
&lt;p&gt;I typically store this file in my home directory in a path something like:&lt;br /&gt;
&lt;code&gt;/home/[username]/.scripts/download-complete.sh&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;After that you&apos;ll need to make sure you make this an executable script:&lt;br /&gt;
&lt;code&gt;$chmod +x /home/[username]/.scripts/download-complete.sh&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Last, tell Transmission about the script&lt;/h3&gt;
&lt;p&gt;Transmission has a handy little preference in the &quot;Downloading&quot; tab that lets you &quot;Call script when torrent is completed&quot;. Just supply this with your newly created download-complete.sh file, and you are all set. Next time a download completes, you should get a push notification to your mobile device about it.&lt;/p&gt;
</content:encoded></item><item><title>Removing another plugins hooks</title><link>https://chrisk.io/posts/removing-another-plugins-hooks/</link><guid isPermaLink="true">https://chrisk.io/posts/removing-another-plugins-hooks/</guid><description>The Problem Recently, I was working on a support thread where the user was attempting to override the default functionality of Easy Digital Downloads by…</description><pubDate>Mon, 03 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h5&gt;The Problem&lt;/h5&gt;
&lt;p&gt;Recently, I was working on a support thread where the user was attempting to override the default functionality of Easy Digital Downloads by using the &lt;code&gt;remove_action()&lt;/code&gt; function. This was being done in a custom plugin. This function allows you to negate any &lt;code&gt;add_action()&lt;/code&gt; created by another plugin, theme, or WordPress core. Their code, at a basic level, looked like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;?php
/**
* Plugin Name: Some Custom Plugin
* Plugin URI:  ...
* Description: Another custom plugin
* Author:      ...
* Author URI:  ...
* Version:     ...
* Text Domain: ...
*/&lt;/p&gt;
&lt;p&gt;remove_action( &apos;edd_purchase_form_after_user_info&apos;, &apos;edd_user_info_fields&apos; );&lt;br /&gt;
remove_action( &apos;edd_register_fields_before&apos;, &apos;edd_user_info_fields&apos; );&lt;/p&gt;
&lt;p&gt;function new_edd_user_info_fields() {&lt;br /&gt;
// Replace the checkout form user fields&lt;br /&gt;
}&lt;br /&gt;
add_action( &apos;edd_purchase_form_after_user_info&apos;, &apos;new_edd_user_info_fields&apos; );&lt;br /&gt;
add_action( &apos;edd_register_fields_before&apos;, &apos;new_edd_user_info_fields&apos; );&lt;/p&gt;
&lt;p&gt;In short, they were trying to write a custom set of customer info fields on the checkout screen, by overriding the defaults using &lt;code&gt;remove_action&lt;/code&gt;. This wasn&apos;t working for them however...I&apos;ll give you a second to think about why. Go ahead, get your thoughts in &lt;em&gt;order&lt;/em&gt;.&lt;/p&gt;
&lt;h5&gt;The Explanation&lt;/h5&gt;
&lt;p&gt;The issue at hand, is plugin load order. WordPress loads the code for plugins in the following order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Must Use Plugins (or mu-plugins)&lt;/li&gt;
&lt;li&gt;Network Activated Plugins (if it&apos;s a multisite install)&lt;/li&gt;
&lt;li&gt;Plugins in the &apos;plugins_activated&apos; option in &lt;strong&gt;alphabetical order&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What was basically happening, is this custom plugin was loading &lt;em&gt;before&lt;/em&gt; Easy Digital Downloads, resulting in the &lt;code&gt;remove_action()&lt;/code&gt; was being called before the &lt;code&gt;add_action()&lt;/code&gt; that EDD was using.&lt;/p&gt;
&lt;h5&gt;The Solution&lt;/h5&gt;
&lt;p&gt;So how did we solve it? Pretty easily actually...&lt;/p&gt;
&lt;p&gt;add_action( &apos;plugins_loaded&apos;, &apos;ck_edd_remove_personal_info&apos;, 99 );
function ck_edd_remove_personal_info() {
remove_action( &apos;edd_purchase_form_after_user_info&apos;, &apos;edd_user_info_fields&apos; );
remove_action( &apos;edd_register_fields_before&apos;, &apos;edd_user_info_fields&apos; );
}&lt;/p&gt;
&lt;p&gt;What this allowed us to do is wait until the last possible moment of the &lt;code&gt;plugins_loaded&lt;/code&gt; hook using the &apos;99&apos; parameter for order, and then tell WordPress to remove the hooks run by EDD. Then we were free to add our own hooks to make a personalized checkout screen.&lt;/p&gt;
&lt;h5&gt;Any gotchas?&lt;/h5&gt;
&lt;p&gt;As with all software development, there&apos;s probably a few edge cases where this won&apos;t work. If the hooks and filters are determining anything before the end of plugins loaded, you might have an issue, but for most general use cases, this should do the trick.&lt;/p&gt;
</content:encoded></item><item><title>Lessons I&apos;ve Learned from Enterprise Software Development</title><link>https://chrisk.io/posts/enterprise-development-lessons/</link><guid isPermaLink="true">https://chrisk.io/posts/enterprise-development-lessons/</guid><description>No matter how many personal projects, open-source projects, or GitHub repos you&apos;ve submitted changes to...nothing can prepare you for the arduous process…</description><pubDate>Sat, 01 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;No matter how many personal projects, open-source projects, or GitHub repos you&apos;ve submitted changes to...nothing can prepare you for the arduous process that enterprise level software development can be. I moved from the &apos;DIY&apos; development realm into an enterprise development position almost 4 years ago now, and while I&apos;ve found many things that just frustrate me to no end, there are a few things that I&apos;ve taken into practice in my own personal projects that make my life easier. These are lessons from the trenches of enterprise software development, and I hope you find them useful.&lt;/p&gt;
&lt;h2&gt;My Lessons in Enterprise Development&lt;/h2&gt;
&lt;h5&gt;Change Management Is Important&lt;/h5&gt;
&lt;p&gt;So what&apos;s the biggest difference? For the most part, process. Enterprise level development (and deployment) ~is~ &lt;em&gt;should&lt;/em&gt; be a heavily documented process. Being able to track changesets, deployments, and configuration changes is very important. This leads to the ability to rollback changes that cause negative impact. This isn&apos;t just for blame, like you might think. It&apos;s great for future changes that may have similar impact. You can learn from past deployments better, when it&apos;s documented.&lt;/p&gt;
&lt;h5&gt;Formal Code Reviews Are Worth the Time&lt;/h5&gt;
&lt;p&gt;In the open-source community, our code is out there for the public to see, but how many people actually review the code as a whole? A common practice with enterprise development process is the &apos;code review&apos;. This is having a peer or manager look over change sets to see if you&apos;ve missed an edge case, made a minor mistake, or to suggest other naming conventions.&lt;/p&gt;
&lt;p&gt;Code reviews lead to code that&apos;s easier to maintain, because you&apos;ve gotten the opinion of another developer before it&apos;s even released. It also tends to lead to much more readable code. When you know someone else is going to read the code, in depth, you take more time making sure it&apos;s commented, and legible. Tools like GitHub make this a much easier process as well, since you can use Pull Requests and line-by-line comments during the code review.&lt;/p&gt;
&lt;h5&gt;Never Underestimate the Power of Requirements&lt;/h5&gt;
&lt;p&gt;There&apos;s a time and place for ad-hoc feature additions, and it&apos;s not very often. Features should come with a list of requirements. This is how you measure weather or not you&apos;ve successfully completed development. Without it, you are stuck in an endless &quot;...just one more thing&quot; phase. You can see more on why this is important in my post &lt;a href=&quot;https://chrisk.io/2013/07/the-power-of-pause-know-when-to-stop/&quot;&gt;&quot;The Power Of Pause&quot;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In my experience with enterprise development, requirements are usually (at a minimum) thought through at a high level before the developer even sees them. While they aren&apos;t always perfect, they are a clear start and end point, which makes development much more measurable. Where requirements also come into play are with Quality Assurance. Weather you are using Test Driven Development or Waterfall, at some point your code needs to &apos;pass&apos; and requirements are a very clear list of test &apos;assertions&apos; that need to pass.&lt;/p&gt;
&lt;h5&gt;Act on data, not Instinct&lt;/h5&gt;
&lt;p&gt;Notice I didn&apos;t say &apos;ignore instinct&apos;. Instinct in a developer has it&apos;s place. It helps us narrow down causes while troubleshooting, helps us in the early stages of writing our apps, and in general helps you avoid issues later on based off past experiences.&lt;/p&gt;
&lt;p&gt;Where instinct should be avoided is when making crucial decisions to infrastructure, application performance, and deployment issues. Always trust data. You should be using something like &lt;a href=&quot;https://chrisk.io/NewRelic&quot;&gt;New Relic&lt;/a&gt; or a code profiler to tell you how much faster your site is running after your release. Testing pricing or copy changes? &lt;a href=&quot;https://chrisk.io/optimizely&quot;&gt;Optimizley is a great tool&lt;/a&gt; and will give you a clear winner.&lt;/p&gt;
&lt;p&gt;If you can&apos;t give a statistic for a decision between two choices, then don&apos;t make the change. Use the vast number of tools at your disposal to get a clear &apos;winner&apos;. If you aren&apos;t in production yet, employ User Groups to test changes in designs. If your response to &apos;Why color 1 over color 2?&apos; is &apos;It pops&apos;, you&apos;re doing it wrong.&lt;/p&gt;
&lt;p&gt;These are just a few things I&apos;ve learned since entering the corporate development environment. If you have others that you stand by, drop them in the comments and let me know.&lt;/p&gt;
</content:encoded></item><item><title>My Return to the Customer Support World</title><link>https://chrisk.io/posts/return-customer-support-world/</link><guid isPermaLink="true">https://chrisk.io/posts/return-customer-support-world/</guid><description>Anyone who tells you doing customer support is easy, is either lying, naive, or insane...or some combination of all three. It&apos;s a hard role that will try…</description><pubDate>Fri, 28 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Anyone who tells you doing customer support is easy, is either lying, naive, or insane...or some combination of all three. It&apos;s a hard role that will try your patience on a daily (sometimes hourly) basis.&lt;/p&gt;
&lt;p&gt;How do I know? I did it for 2.5 years. My experiences ranged from being the person you talked to when you wanted to buy a domain, all the way up to tracking and identifying trending issues to either get the operations center and developers out of bed at 1am, or provide detailed steps to reproduce a bug identified by our customers. I preferred the latter of those two. Developers are grumpy at 1am.&lt;/p&gt;
&lt;p&gt;That was almost 4 years ago now.&lt;/p&gt;
&lt;h5&gt;So why am I doing customer support again?&lt;/h5&gt;
&lt;p&gt;I didn&apos;t really choose to go into support. I actually choose to write a plugin, and then build paid extensions for that plugin. By proxy, that means I&apos;m choosing to do customer support. When you decide to build anything that you distribute (especially if it&apos;s a paid product) you are choosing to be a customer support representative for yourself. No matter the plugin, app, SaaS, or anything else...support comes along for the ride. Accepting this ahead of time and planning for it will save you the heartbreak later.&lt;/p&gt;
&lt;h5&gt;Support as a feature&lt;/h5&gt;
&lt;p&gt;Have you ever looked at your favorite grocery store item? They all have a phone number to call if you want to leave &quot;Questions, Comments, or Concerns&quot;. Have you actually called that number to tell them their product was great? Probably not. Do you buy these products solely based on the fact that the phone number is there? Probably not.&lt;/p&gt;
&lt;p&gt;The software world is different though. Before we purchase a piece of software, we want to know it&apos;ll be supported. We want to know that we can hold someone accountable for mistakes we find. Sometimes, that comes is pretty harsh criticism. How you handle feedback (both positive and negative) can, and should, be one of your best selling points.&lt;/p&gt;
&lt;p&gt;Just recently I started as a Support Technician for &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads&lt;/a&gt;, a project I&apos;ve contributed to as well as written paid extensions for. One of the first realizations I had was that people came to these forums &lt;em&gt;expecting&lt;/em&gt; great support. It&apos;s something the team prides themselves in and it&apos;s reflected in the &lt;a href=&quot;http://wordpress.org/support/view/plugin-reviews/easy-digital-downloads?filter=5&quot;&gt;reviews left on WordPress.org&lt;/a&gt;. With so many people listing it in their review, it&apos;s clearly a feature of the plugin.&lt;/p&gt;
&lt;h5&gt;My thoughts on customer support as a developer&lt;/h5&gt;
&lt;p&gt;Customer support is the most difficult task you&apos;ll have to encounter writing software, and it&apos;s simply because of the following fact:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;No one wants to hear they have an ugly baby.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The fact of the matter is, that there are bugs. When they are called out publicly it hurts a little. Being able to take criticism, requests, and being general cannon fodder is a fact of life. Doubly so when you are putting your &quot;life&quot; out there for people to use and see. I&apos;ve seen biggest enemies become life long customers, and fanboys be scorned for life in a single key stroke.&lt;/p&gt;
&lt;p&gt;Make the best of it, be humble, and always be gracious. For every 1 critique, there&apos;s another 10 that never said anything. Use the feedback to make your project better.&lt;/p&gt;
</content:encoded></item><item><title>Undo git pull</title><link>https://chrisk.io/posts/undo-git-pull/</link><guid isPermaLink="true">https://chrisk.io/posts/undo-git-pull/</guid><description>So this morning I was updating my local development environment and getting the latest code from the upstream repo of a project I have forked on GitHub when…</description><pubDate>Thu, 23 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So this morning I was updating my local development environment and getting the latest code from the upstream repo of a project I have forked on GitHub when I suddenly needed to undo a git pull. For some clarity, my method of forking is done &lt;a href=&quot;https://help.github.com/articles/fork-a-repo&quot;&gt;as suggested by GitHub themselves&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The project I&apos;m working on has recently split a new branch for an upcoming 2.0 version, while nightly work is done on master and will likely be released as something like 1.9.5. I have been taking care of some tickets on a branch named &lt;code&gt;release/2.0&lt;/code&gt; but this morning was going to check something out in &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I logged in as I normally do, typed &lt;code&gt;git pull upstream master&lt;/code&gt; and low and behold, was presented with a merge comment suggestion of &lt;code&gt;Merge branch &apos;master&apos; of https://github.com/easydigitaldownloads/Easy-Digital-Downloads into release/2.0&lt;/code&gt;. Face...meet palm. If you use git often, you know what I just did...but if you don&apos;t let me explain:&lt;/p&gt;
&lt;p&gt;Master and release/2.0 are branches of the code base that, at one some point in the future will be merged. Today is not that day, and I&apos;m not the person to do this. Because I had been working on the release/2.0 branch, when I typed my pull from upstream master, it merged the master branch of the primary project, with my local copy of the release/2.0.&lt;/p&gt;
&lt;p&gt;I totally panicked for a second, thinking I&apos;d have to delete and re-clone, but I found a way around this. Two great commands can fix this issue, if you happen to go down the same path I did.&lt;/p&gt;
&lt;h5&gt;Step 1: Determine the Hash of the previous HEAD&lt;/h5&gt;
&lt;p&gt;Using the &lt;code&gt;git reflog&lt;/code&gt; command, we can get a list of the last 15 references or hashes. Mine looked something like this:&lt;/p&gt;
&lt;p&gt;user@host:path$ git reflog
9d80215 HEAD@{0}: pull upstream master: Merge made by the &apos;recursive&apos; strategy.
5f6c496 HEAD@{1}: pull: Fast-forward
3b3c6a4 HEAD@{2}: commit (merge): Fixing formatting, removing tests for further debugging, and fixing filter spelling for args&quot;
bec0786 HEAD@{3}: commit: Fixing formatting issues, spelling issue, and removing tests for the moment
f6dd939 HEAD@{4}: commit: Fixing assertion for post type in unit tests
03f5507 HEAD@{5}: commit: Adding Unit tests for new function edd_get_users_purchased_products()
c517bf9 HEAD@{6}: checkout: moving from master to release/2.0
83ff820 HEAD@{7}: checkout: moving from release/2.0 to master
c517bf9 HEAD@{8}: commit: #1874 - purcahsed products list for a given user
c028f7d HEAD@{9}: checkout: moving from master to release/2.0
83ff820 HEAD@{10}: pull: Fast-forward
069aa66 HEAD@{11}: pull upstream master: Fast-forward
8c57661 HEAD@{12}: pull upstream master: Fast-forward
37a57c2 HEAD@{13}: pull upstream master: Fast-forward
6b01ff4 HEAD@{14}: clone: from git@github.com:cklosowski/Easy-Digital-Downloads.git&lt;/p&gt;
&lt;p&gt;We can see my &apos;oops&apos; is &lt;code&gt;HEAD@{0}&lt;/code&gt;, which means, I want the hash of &lt;code&gt;HEAD@{1}&lt;/code&gt; or &lt;code&gt;5f6c496&lt;/code&gt;.&lt;/p&gt;
&lt;h5&gt;Step 2: Reset my local branch&lt;/h5&gt;
&lt;p&gt;Using the has above, we can now use the &lt;code&gt;git reset&lt;/code&gt; command to get local copy of this branch, back to the state the remote is in, and no one will be the wiser.&lt;/p&gt;
&lt;p&gt;user@host:path$ git reset --hard &amp;lt;hash found above&amp;gt;&lt;/p&gt;
&lt;p&gt;Hit enter, and then run a &lt;code&gt;git status&lt;/code&gt; where you should see a message of something that reads like &lt;code&gt;nothing to commit, working directory clean&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;SUCCESS! We&apos;ve now unmerged the pull and merge we did by accident and we can continue coding like nothing ever happened.&lt;/p&gt;
&lt;h5&gt;Caveats&lt;/h5&gt;
&lt;p&gt;By doing this, any work you&apos;ve done between the last successful commit and this pull will be lost. Be sure to stash that away somewhere before you run these commands or you will need to recode it.&lt;/p&gt;
&lt;p&gt;[kofi]&lt;/p&gt;
</content:encoded></item><item><title>An issue for every commit</title><link>https://chrisk.io/posts/issue-every-commit/</link><guid isPermaLink="true">https://chrisk.io/posts/issue-every-commit/</guid><description>Over this past weekend at WordCamp Phoenix , I had the pleasure of sitting down with the 3/4 of the Easy Digital Downloads core development team. Pippin,…</description><pubDate>Wed, 22 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Over this past weekend at &lt;a href=&quot;http://2014.phoenix.wordcamp.org/&quot;&gt;WordCamp Phoenix&lt;/a&gt;, I had the pleasure of sitting down with the 3/4 of the &lt;a href=&quot;https://chrisk.io/EDD&quot;&gt;Easy Digital Downloads&lt;/a&gt; core development team. Pippin, Dan, and Chris traveled from their respective hometowns to attend a WordCamp in my backyard. This was the first time I&apos;d had a chance to meet Dan and Chris in person, although we&apos;ve gone back and forth on many of GitHub issues.&lt;/p&gt;
&lt;p&gt;Which brings me to the point of writing this. At one point I believe Chris had stumbled upon a bit of code he wanted to commit, and when asked what &apos;issue&apos; it was related to, we all had a small discussion on commits and how they should always be tied to an issue (or ticket, project, etc). I use the word &apos;issue&apos; as that&apos;s the way GitHub tracks a project&apos;s bugs, enhancements, discussions, etc.&lt;/p&gt;
&lt;h5&gt;It&apos;s all relative&lt;/h5&gt;
&lt;p&gt;So why an issue to every commit?! This isn&apos;t really the case, not every commit needs it&apos;s own issue, but every commit should relate to an issue. Weather it&apos;s existing, or you are creating it for this specific commit, there needs to be some sort of documentation of why the change is being made, what kind of change it is, and from there, all related change sets that relate to it.&lt;/p&gt;
&lt;p&gt;If you have multiple files being edited, only commit files together if their changes are related. This helps the rollback process, when you can easily revert a changeset and all related changes are reversed, while unrelated changes are kept in their own revision.&lt;/p&gt;
&lt;p&gt;Ad-Hoc changes are not only a challenge to track down if a bug arrises later, but it leads to a messy codebase where not all parties involved are aware of changes and their reasoning.&lt;/p&gt;
&lt;h5&gt;Meaningful messages tell a story&lt;/h5&gt;
&lt;p&gt;I&apos;ll be honest, when it&apos;s time to release, having the ability to just look at your commit messages and easily summarize what was changed is a godsend. It also helps you scope a release and the possible impact it may have. Each commit you make should have a meaningful message with it. &quot;Updating Header&quot; or &quot;deleting stuff&quot; doesn&apos;t quite cut it. Not only does it make looking through issues later difficult, but it shows a lack of care and pride in what you just accomplished. I&apos;ll be honest, I&apos;ve done it once or twice, but try not to make it a habit.&lt;/p&gt;
&lt;h5&gt;Tools to do the job&lt;/h5&gt;
&lt;p&gt;Most developers have a few things in the air at once, and what happens if you have multiple changes to a file, but you only want to commit part of it!? These changes aren&apos;t related and in fact, belong to different issues?! What is a developer to do? &lt;code&gt;git add -p&lt;/code&gt; to the rescue. This command allows you to commit specific parts of a file, instead of all changes in the file. This is a great way to work in parallel, while keeping your commits tied to separate issue.&lt;/p&gt;
&lt;p&gt;So be sure to write up that bug, enhancement, or feature next time you start coding and drop some project requirements in there while you are at it. Let&apos;s focus on making your projects as manageable as possible.&lt;/p&gt;
&lt;p&gt;What are some of your practices when it comes to issue tracking and commits?&lt;/p&gt;
</content:encoded></item><item><title>Plugin: WP e-Commerce Status Board</title><link>https://chrisk.io/posts/plugin-wp-e-commerce-status-board/</link><guid isPermaLink="true">https://chrisk.io/posts/plugin-wp-e-commerce-status-board/</guid><description>A while back I wrote about integrating WordPress plugins with Panic&apos;s Status Board iPad App , and while the plugin has been soft launched for about a month…</description><pubDate>Tue, 03 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A while back I wrote about &lt;a href=&quot;https://chrisk.io/2013/05/integrating-status-board-with-wordpress-plugins/&quot;&gt;integrating WordPress plugins with Panic&apos;s Status Board iPad App&lt;/a&gt;, and while the plugin has been soft launched for about a month while I listen for user feedback...I&apos;m happy to announce that &lt;a href=&quot;http://wordpress.org/plugins/wpec-status-board/&quot;&gt;WP e-Commerce Status Board is available on the WordPress.org repo&lt;/a&gt;. With this Status Board widget, you&apos;ll be able to track your sales and earnings in WP e-Commerce on one graph, on your iPad:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/screenshot-1-1.png&quot;&gt;&lt;img src=&quot;/images/blog/screenshot-1-234x300-1.png&quot; alt=&quot;screenshot-1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To add this widget to Status Board, simply login to your WP e-Commerce site on your iPad, view your Sales Logs page, and at the bottom of the page is a button to add your stats to Status Board.&lt;/p&gt;
&lt;p&gt;If you have any questions or issues check out the contextual help at the top right of the Sales Logs page and if that doesn&apos;t help, please use the &lt;a href=&quot;http://wordpress.org/support/plugin/wpec-status-board&quot;&gt;WordPress.org Support Forum&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A big thanks to &lt;a href=&quot;https://twitter.com/danmilward&quot;&gt;Dan Milward&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/JS_Zao&quot;&gt;Justin Sainton&lt;/a&gt; for their discussions and testing.&lt;/p&gt;
</content:encoded></item><item><title>New Features and the Tyranny of the Default</title><link>https://chrisk.io/posts/new-features-and-the-tyranny-of-the-default/</link><guid isPermaLink="true">https://chrisk.io/posts/new-features-and-the-tyranny-of-the-default/</guid><description>It&apos;s happened to all of us at some point or another. We see the shiny &apos;Update&apos; button on our WordPress dashboard, phone, or other platform with excitement…</description><pubDate>Wed, 28 Aug 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s happened to all of us at some point or another. We see the shiny &apos;Update&apos; button on our WordPress dashboard, phone, or other platform with excitement and can&apos;t wait until it&apos;s done so we can play with our new shiny features. Most of the time new features are a welcome addition and we want them on, but what happens when a new feature actually hurts you or has an unwanted outcome?&lt;/p&gt;
&lt;p&gt;Think in the terms of an SEO plugin (I&apos;m not naming names or even thinking of one specifically). Many companies or businesses spend hours, days, or weeks properly setting up their SEO strategy. They execute this in their plugin, then on the next &apos;update&apos; a new feature is added that auto enabled a feature they weren&apos;t aware of, changing their SEO footprint. It may take weeks for them to realize why their page ranks have changed and traffic is down. There are plenty of other cases. WordPress themes for instance, can sometimes add new features that conflict with plugins installed to do the same thing. Maybe colorblox/floatbox/*box was added to the theme, but the user already has a plugin installed to handle this.&lt;/p&gt;
&lt;p&gt;I think my point comes across pretty clearly in those two cases. If you are adding features to your plugins, apps and platforms you should be thinking of the impact you may have on your users before you default that setting to &apos;On&apos;. I prefer to err on the side of caution and make my new features &apos;Opt In&apos;, due to their usage of an external API and interrupting a users&apos; day with push notifications.&lt;/p&gt;
&lt;p&gt;What are your thoughts on new features and their implementation?&lt;/p&gt;
</content:encoded></item><item><title>Plugin: Simple Notices for Responsive</title><link>https://chrisk.io/posts/simple-notices-for-responsive/</link><guid isPermaLink="true">https://chrisk.io/posts/simple-notices-for-responsive/</guid><description>I&apos;ve been using it for quite some time, but the other day I just pushed a new plugin to Github that users of the &quot; Responsive &quot; WordPress theme might find…</description><pubDate>Sun, 28 Jul 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been using it for quite some time, but the other day I just pushed a new plugin to Github that users of the &quot;&lt;a href=&quot;http://wordpress.org/themes/responsive&quot;&gt;Responsive&lt;/a&gt;&quot; WordPress theme might find useful. It&apos;s called &quot;&lt;a href=&quot;https://github.com/cklosowski/simple-notices-for-responsive&quot;&gt;Simple Notices for Responsive&lt;/a&gt;&quot; and I&apos;d love it if you&apos;d take it for a spin on your Responsive powered website.&lt;/p&gt;
&lt;p&gt;Originally I wrote it for &lt;a href=&quot;https://wp-push.com&quot;&gt;WP-Push.com&lt;/a&gt;, so I could announce new plugins or discounts. I figured it was useful enough to give to the masses. Since it&apos;s initial push, I&apos;ve added the color picker and a live updated preview to the admin settings. Here are some screenshots...&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/admin-settings.png&quot;&gt;&lt;img src=&quot;/images/blog/admin-settings-300x228.png&quot; alt=&quot;The Admin Settings View&quot; /&gt;&lt;/a&gt; The Admin Settings View&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/front-end.png&quot;&gt;&lt;img src=&quot;/images/blog/front-end-300x110.png&quot; alt=&quot;The Front End View&quot; /&gt;&lt;/a&gt; The Front End View&lt;/p&gt;
</content:encoded></item><item><title>The Power of Pause: Know when to stop</title><link>https://chrisk.io/posts/the-power-of-pause-know-when-to-stop/</link><guid isPermaLink="true">https://chrisk.io/posts/the-power-of-pause-know-when-to-stop/</guid><description>For most software developers, working on a project is just taking a predetermined set of requirements, translating them into sudo-code, writing some code,…</description><pubDate>Fri, 05 Jul 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For most software developers, working on a project is just taking a predetermined set of requirements, translating them into sudo-code, writing some code, and handing it off to a QA for testing. You&apos;re goals or iterations are well-defined by either a manager or marketing type. The design is constructed by the creative department. The usability team has run it by a user-based test group. You&apos;re on your way to a pretty uneventful iteration.&lt;/p&gt;
&lt;p&gt;What? That doesn&apos;t happen for you? Don&apos;t worry, you aren&apos;t alone. One thing I&apos;ve found is that it&apos;s often hard to know where you stopping point is, even with a defined set of iterations. If you find yourself saying &quot;Just one more [&lt;em&gt;something&lt;/em&gt;]...&quot; then you need to stop.&lt;/p&gt;
&lt;h3&gt;The Power of Pause&lt;/h3&gt;
&lt;p&gt;A while back I picked up &lt;a href=&quot;http://www.amazon.com/gp/product/020161622X/ref=as_li_ss_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=020161622X&amp;amp;linkCode=as2&amp;amp;tag=chrkdes-20&quot;&gt;&quot;The Pragmatic Programmer: From Journeyman to Master&quot;&lt;/a&gt;. If the title doesn&apos;t tell you enough, it&apos;s about taking your software development skills far beyond specifics and into concepts. Anyway, one of the sections is titled &quot;Know When to Stop&quot;.&lt;/p&gt;
&lt;h5&gt;Know When to Stop&lt;/h5&gt;
&lt;p&gt;As an art school graduate, this phrase is ingrained into my creative conscious. Much like painting or sculpting, software development can often become a game of knowing when to stop. You may not always stop entirely, but you need to pause, let the current work &apos;bake&apos;, and then come back to it. The important part is, you take a break from the project.&lt;/p&gt;
&lt;p&gt;Far too often, we get into a downward spiral of features, bells, and whistles that just clutter our projects. The quote from the book you should remember is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Don&apos;t spoil a perfectly good program by overembellishment and over-refinement. Move on, and let your code stand in its own right for a while.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It may turn out that what you&apos;ve done is a perfectly balanced user experience, or it could be the most confusing experience ever. Either way, once the paint hits the canvas it&apos;s hard to take it back. This stands true in software development as well. Once features are released, removing them can be time-consuming, and in some cases, disruptive.&lt;/p&gt;
&lt;h5&gt;How long should I stop for?&lt;/h5&gt;
&lt;p&gt;This depends on the person and/or project. Usually, I&apos;ll let a development project sit in my development environment for a day or two before I get anywhere near pushing it to a QA. As I&apos;ve stated before, &lt;a href=&quot;https://chrisk.io/building-plugins-hard/&quot;&gt;developing something you don&apos;t use isn&apos;t easy&lt;/a&gt;. By leaving the code there for a day or two, without actively developing, you can use and interact with the project as a whole, instead of a single feature.&lt;/p&gt;
&lt;p&gt;Sometimes, it simply takes a lunch break for me to realize that I don&apos;t need to take a project any further. The point is, get your head out of the forest and step back to see what you are up against.&lt;/p&gt;
&lt;h5&gt;Built in breakpoints&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;/images/blog/2012-09-13-14.54.43-224x300.jpg&quot; alt=&quot;2 pages of notes, only half of it made into the next iteration.&quot; /&gt; The original list of features for &lt;a href=&quot;https://wp-push.com/&quot;&gt;Pushover Notifications for WordPress&lt;/a&gt;. Only half of these made the next iteration.&lt;/p&gt;
&lt;p&gt;Most software developers should be familiar with the term &apos;&lt;a href=&quot;http://en.wikipedia.org/wiki/Breakpoint&quot;&gt;breakpoints&lt;/a&gt;&apos;. I like to use this pattern in my software development life cycle (SDLC) as well. I typically start with a list of &quot;must haves&quot;. Then I create a list of &quot;nice to haves&quot; and &quot;future release&quot; features or goals.&lt;/p&gt;
&lt;p&gt;Once my &quot;must haves&quot; are complete, I reassess my remaining two lists. Since a project can change a bit between concept and the first iteration, stopping at each pass allows you to see if your original list of features are even necessary for this release.&lt;/p&gt;
&lt;h5&gt;What&apos;s your process&lt;/h5&gt;
&lt;p&gt;Clearly, this is a very individualized topic...so what&apos;s your secret? Do you just go head down to get a project done? When and how do you define your stopping point? Are you a &apos;Kanban board&apos; type person, or do you work pen and paper? I&apos;d be curious to see what other people do to help to Know When to Stop.&lt;/p&gt;
</content:encoded></item><item><title>A Call For Changelog Transparency</title><link>https://chrisk.io/posts/a-case-for-changelog-transparency/</link><guid isPermaLink="true">https://chrisk.io/posts/a-case-for-changelog-transparency/</guid><description>The other day I was notified by the iOS App Store that two of my apps had available updates. I always get excited when updates come. &quot;Is it new features?…</description><pubDate>Sun, 23 Jun 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The other day I was notified by the iOS App Store that two of my apps had available updates. I always get excited when updates come. &quot;Is it new features? Long standing annoyances fixed? Performance boosts?&quot; All to often though this is all I see:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/bug-fixes.png&quot;&gt;&lt;img src=&quot;/images/blog/bug-fixes-300x216.png&quot; alt=&quot;bug-fixes&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&quot;- Bug Fixes&quot; is possibly my biggest pet-peeve practice of software developers. Great you fixed some stuff. Was it 1 bug or 100 bugs? Were they security related? Is it the bug I told your support staff about months ago? I&apos;ll never know because of this changelog. One thing that a professional developer does is take ownership of their code. If you made the mistake, take the blame. Changelog transparency is just one way of doing this. Being clear about what you change leads to being clear about what you have/are doing.&lt;/p&gt;
&lt;h4&gt;How embarrassing...&lt;/h4&gt;
&lt;p&gt;Look, as a developer I get it. Sometimes your bug fixes are because you did something you find &quot;stupid&quot;, and that&apos;s embarrassing. Misspelling a variable or function name, not verifying a data set, or just general mistakes sometimes sneak their way into a commit. That happens. But why hide the fact that you aren&apos;t perfect? You don&apos;t have to go into details, but you could explain what your bug fix...well...fixes! That&apos;s a novel idea. Transparency in your mistakes.&lt;/p&gt;
&lt;h4&gt;Identify new bugs&lt;/h4&gt;
&lt;p&gt;One other reason to be more clear of your &quot;bug fixes&quot; is to allow new bugs to be identified easier. If your new code introduces a bug, having a list of items you did in the last release might help you narrow down your debugging window. One of the primary focuses of change management is logging every change. If something goes wrong during a deployment or release, giving proper information can help avoid hours of lost time tracking down a bug.&lt;/p&gt;
&lt;h4&gt;When did we add that one feature that does that one thing?&lt;/h4&gt;
&lt;p&gt;If your a developer who iterates quickly, you might easily forget when you made a specific change or added a new feature. Here comes the changelog to the rescue. I prefer to list each item in my change log with one of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FIX - For bug fixes&lt;/li&gt;
&lt;li&gt;NEW - For new features&lt;/li&gt;
&lt;li&gt;ENHANCEMENT - For smaller updates to current features&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So let&apos;s try and give our users and other developers a little more transparency when we push a new release and avoid using &apos;Bug Fixes&apos; in our changelogs. Here are two changelogs for WordPress plugins that you can take examples from:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://wordpress.org/plugins/wordpress-seo/changelog/&quot;&gt;WordPress SEO by Yoast&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://wordpress.org/plugins/easy-digital-downloads/changelog/&quot;&gt;Easy Digital Downloads&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>The benefits of WordPress actions and filters</title><link>https://chrisk.io/posts/the-benefits-of-wordpress-actions-and-filters/</link><guid isPermaLink="true">https://chrisk.io/posts/the-benefits-of-wordpress-actions-and-filters/</guid><description>As a WordPress plugin developer, the 3 most important things I put in my code are: Translatable Text (__, _e, _n, etc) apply_filters do_action Why are those…</description><pubDate>Fri, 07 Jun 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a WordPress plugin developer, the 3 most important things I put in my code are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Translatable Text (__, _e, _n, etc)&lt;/li&gt;
&lt;li&gt;apply_filters&lt;/li&gt;
&lt;li&gt;do_action&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Why are those the most important, you might ask? Freedom. They are important because they allow any user or developer to bend my plugins to their specific needs. The whole POINT of the plugin system for WordPress is to &lt;em&gt;help&lt;/em&gt; people extend their site to be so much more than a standard blogging platform. I was looking into building a new (and free) Pushover Notification extension for a plugin tonight, when I came across something that frustrated the heck out of me.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Plugin Downloads: 1,717,451&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Searching 138 files:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search code for do_action: 0 found&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search code for apply_filters: 3 found&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One of the top 20 plugins on the WordPress repository, with almost 1.75 million downloads, has but a TRACE of extensibility.&lt;/p&gt;
&lt;p&gt;To contrast, let me give you some stats on another plugin:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Plugin Downloads: 99,948&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Searching 296 files:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search code for do_action: 217 found across 45 files&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search code for apply_filters: 280 found across 50 files&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add On Plugins: ~126&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because this second plugin is so extensibile, at least 126 &apos;extensions&apos; have been created to make this plugin extend past it&apos;s core functionality. This is all due to the inclusion of almost 500 points of integration that the developers have created.&lt;/p&gt;
&lt;p&gt;My frustration with the first plugin is that, because the developers simply didn&apos;t think it was necessary to use actions and filters, the plugin can never become more than the sum of it&apos;s own parts. This saddens me as a developer, but more as a WordPress user and community member.&lt;/p&gt;
&lt;p&gt;If you aren&apos;t including actions and filters in your plugins because you aren&apos;t quite sure where to get started, that&apos;s ok, we&apos;ve all been at that point. Start by reading up on the codex pages for both:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://codex.wordpress.org/Function_Reference/do_action&quot;&gt;do_action&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://codex.wordpress.org/Function_Reference/apply_filters&quot;&gt;apply_filters&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tom McFarlin also wrote up a great &lt;a href=&quot;http://wp.tutsplus.com/tutorials/the-beginners-guide-to-wordpress-actions-and-filters/&quot;&gt;Beginners Guide to WordPress Actions and Filters&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now go out and start applying filters and doing actions!&lt;/p&gt;
</content:encoded></item><item><title>Beer-Cheese Burgers and Hockey</title><link>https://chrisk.io/posts/beer-cheese-burgers-and-hockey/</link><guid isPermaLink="true">https://chrisk.io/posts/beer-cheese-burgers-and-hockey/</guid><description>Tonight, we dined true &quot;Midwestern-er Style&quot;, making burgers with Beer-Cheese Sauce, lettuce, and tomato along with some left over German Style Potato…</description><pubDate>Wed, 29 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Tonight, we dined true &quot;Midwestern-er Style&quot;, making burgers with Beer-Cheese Sauce, lettuce, and tomato along with some left over German Style Potato Salad...while watching the Red Wings take on the Blackhawks in the NHL Western Conference Semi-finals.&lt;/p&gt;
&lt;p&gt;This turned out to be, dare I say, one of the best burgers we&apos;ve made. Simple, subtle, yet really flavorful and juicy. We used an 80/20 Ground Angus Beef (grilled) and some left over Budweiser (not light). Not my typical beer but we had it around the house and it worked really well for this.&lt;/p&gt;
&lt;p&gt;View the &lt;a href=&quot;http://www.foodnetwork.com/recipes/food-network-kitchens/beer-cheese-burgers-recipe/index.html&quot;&gt;recipe and directions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Image courtesy of Food Network.&lt;/p&gt;
</content:encoded></item><item><title>Integrating Status Board with WordPress Plugins</title><link>https://chrisk.io/posts/integrating-status-board-with-wordpress-plugins/</link><guid isPermaLink="true">https://chrisk.io/posts/integrating-status-board-with-wordpress-plugins/</guid><description>Recently, Panic (The software company behind popular OSX Apps Coda and Transmit), released an iPad app called Status Board . I don&apos;t, myself, own an iPad…</description><pubDate>Tue, 07 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently, Panic (The software company behind popular OSX Apps Coda and Transmit), released an iPad app called &lt;a href=&quot;http://panic.com/statusboard/&quot;&gt;Status Board&lt;/a&gt;. I don&apos;t, myself, own an iPad but I know a lot of people who do. I also can&apos;t turn down the opportunity to build something useful that integrates multiple apps, plugins, and data points. Seriously, I think I need help.&lt;/p&gt;
&lt;p&gt;I use &lt;a href=&quot;http://wordpress.org/extend/plugins/jetpack/&quot;&gt;Jetpack&lt;/a&gt; and &lt;a href=&quot;https://easydigitaldownloads.com?ref=371&quot;&gt;Easy Digital Downloads&lt;/a&gt; daily, and know both of them have very &apos;statistical&apos; driven data sets, so I figured, &quot;What the heck. Why not build some Status Board graphs for the people who use these plugins and own an iPad!&quot;&lt;/p&gt;
&lt;p&gt;Enter, &lt;strong&gt;&lt;a href=&quot;http://wordpress.org/extend/plugins/edd-status-board/&quot;&gt;EDD - Status Board&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href=&quot;http://wordpress.org/extend/plugins/jetpack-status-board/&quot;&gt;Jetpack Status Board&lt;/a&gt;&lt;/strong&gt;. These two plugins for WordPress will give you the ability to integrate Easy Digital Downloads&apos; Sales &amp;amp; Earnings and Jetpack daily views into a beautiful Status Board bar graph.&lt;/p&gt;
&lt;p&gt;Here are some screenshots:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/photo.jpg&quot;&gt;&lt;img src=&quot;/images/blog/photo-225x300.jpg&quot; alt=&quot;photo&quot; title=&quot;Jetpack Status Board&quot; /&gt;&lt;/a&gt; Graphs of two sites running Jetpack Status Board&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/screenshot-1.png&quot;&gt;&lt;img src=&quot;/images/blog/screenshot-1-234x300.png&quot; alt=&quot;screenshot-1&quot; title=&quot;EDD - Status Board&quot; /&gt;&lt;/a&gt; Graph of a site running Easy Digital Downloads and EDD - Status Board&lt;/p&gt;
&lt;p&gt;If you have either of these plugins and the Status Board app on your iPad, it would be great if you could give them a shot and provide some feedback. So far the EDD - Status Board plugin has a great review from the Creator and Lead Developer of Easy Digital Downloads:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is integrations like this that validate the entire idea behind building the Easy Digital Downloads jSON API.&lt;/p&gt;
&lt;p&gt;Being able to quickly glance up and see my store&apos;s stats on my iPad display is just awesome.&lt;/p&gt;
&lt;p&gt;Huge props go to Panic for building Status Board, and a big thank you to Chris for taking the time to build the integration.&lt;/p&gt;
&lt;p&gt;- Pippin Williamson (&lt;a href=&quot;http://profiles.wordpress.org/mordauk&quot;&gt;mordauk&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A big thanks to &lt;a href=&quot;http://pippinsplugins.com?ref=67&quot;&gt;Pippin Williamson&lt;/a&gt; and &lt;a href=&quot;http://curtismchale.ca/&quot;&gt;Curtis McHale&lt;/a&gt; for helping me test out the early versions of these plugins.&lt;/p&gt;
&lt;p&gt;If you do happen to try these Status Board plugins out, and find a bug, please report it on the WordPress.org support forums for the plugin, this will help consolidate any bugs you find into one place.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://wordpress.org/support/plugin/edd-status-board&quot;&gt;EDD - Status Board: Support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wordpress.org/support/plugin/jetpack-status-board&quot;&gt;Jetpack Status Board: Support&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Why cleanly formatted code matters</title><link>https://chrisk.io/posts/cleanly-formatted-code-matters/</link><guid isPermaLink="true">https://chrisk.io/posts/cleanly-formatted-code-matters/</guid><description>Being that I work in the software development industry and also work on open source projects, it&apos;s needless to say I&apos;ve seen my fair share of ugly code. I&apos;m…</description><pubDate>Tue, 30 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Being that I work in the software development industry and also work on open source projects, it&apos;s needless to say I&apos;ve seen my fair share of ugly code. I&apos;m not just talking about &apos;poorly engineered&apos; code either. Poor indentation practices, inconsistent variable naming conventions, mixed white space, and comment-less code are all things I identify as ugly code. Some of my own work included. We&apos;ve all got code we&apos;re not proud of. That&apos;s the nature of software development. The key is being able to identify these issues and correct them as time goes on.&lt;/p&gt;
&lt;p&gt;Over the past couple years I&apos;ve started to focus on cleanly formatting my code (on top of properly engineered code of course). It ends with a much nicer product and when I have to troubleshoot later, it&apos;s easier to navigate my previous work. At one point though, I realized that clean code shows craftsmanship.&lt;/p&gt;
&lt;p&gt;Trade-skills are slowly becoming a thing of the past in the digital era. Working with your hands is taking a backseat to typing on a keyboard or pushing a mouse around (myself included), and with that, I think the idea of good craftsmanship can get lost. After all, it&apos;s code, who&apos;s going to see it? Let&apos;s take woodworking for example.&lt;/p&gt;
&lt;p&gt;When I was a kid, my dad spent a lot of time building things out of wood. It would take hours for him to complete a project, but the end result would be beautiful. When I&apos;d work on something, it&apos;d fall apart in a week (come on I was like 10 years old!), but I digress. Now, we could probably all build a table if given the proper materials. You&apos;d first setup your requirements:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements for a Table&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;4 Legs&lt;/li&gt;
&lt;li&gt;Table Top&lt;/li&gt;
&lt;li&gt;Level&lt;/li&gt;
&lt;li&gt;Supports weight&lt;/li&gt;
&lt;li&gt;Proper height&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You need nothing more for that table to be considered a table than those 5 things. Would it be one somebody was proud to put on display? Use daily? Have someone else repair? Probably not, but it&apos;s a table none-the-less.&lt;/p&gt;
&lt;p&gt;So how would you make it something to be proud of?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&apos;d take the time to choose the right wood (maybe a nice dark oak, or walnut)&lt;/li&gt;
&lt;li&gt;You&apos;d sand the top to perfection so there were no bumps from the grain&lt;/li&gt;
&lt;li&gt;You could do inlay patterns with different types of wood&lt;/li&gt;
&lt;li&gt;Add in a removable leaf to expand for the company that comes once a year during a holiday&lt;/li&gt;
&lt;li&gt;Use a more ascetically pleasing joint type, maybe a nice dove tail&lt;/li&gt;
&lt;li&gt;Spend the time to put a few coats of stain on (instead of one) and finish it off with a clear coat&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think it&apos;s pretty obvious to see what I&apos;m getting at. Taking pride in your development work goes FAR beyond what is functionally necessary to meet requirements. Holding yourself to a higher standard in your practices produces something that you can be proud to show off to other developers and shows you take pride in what you do.&lt;/p&gt;
&lt;p&gt;As a software developer, your skill is your ability to quickly adapt and write functional code, but showing a true passion for your skill means treating ever aspect of the job with utmost importance. Even the parts &quot;no one will ever see&quot;. Take the time to determine what you consider &quot;clean code&quot;. If you have tools that you use to achieve this, I&apos;d love to see them in the comments.&lt;/p&gt;
&lt;p&gt;Post image via designandtechnologydepartment @ Flickr&lt;/p&gt;
</content:encoded></item><item><title>Trilogies In Order of Preference</title><link>https://chrisk.io/posts/trilogies-order-preference/</link><guid isPermaLink="true">https://chrisk.io/posts/trilogies-order-preference/</guid><description>One of the developers I follow on Twitter mentioned something about watching the Back to the Future trilogy as a marathon while their baby slept.…</description><pubDate>Sat, 06 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the developers I follow on Twitter mentioned something about watching the Back to the Future trilogy as a marathon while their baby slept.&lt;/p&gt;
&lt;p&gt;https://twitter.com/scottkclark/status/320662470299615232&lt;/p&gt;
&lt;p&gt;That got me to thinking...I love a few trilogies. So I decided to order them in preference:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Star Wars I don’t care if you think there were 6 Star Wars movies…you are wrong. There were 3 Star Wars movies and 3 piles of dog crap released with the Star Wars name so George Lucas could pad the bank accounts. I’ll let you figure out which is which I prefer.&lt;/li&gt;
&lt;li&gt;Lord of the Rings No explination necessary.&lt;/li&gt;
&lt;li&gt;Back to the Future
&lt;ol&gt;
&lt;li&gt;#2&lt;/li&gt;
&lt;li&gt;#1&lt;/li&gt;
&lt;li&gt;#3&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>What font is &quot;Bazinga!&quot; written in?</title><link>https://chrisk.io/posts/font-bazinga-written-in/</link><guid isPermaLink="true">https://chrisk.io/posts/font-bazinga-written-in/</guid><description>Yep, that&apos;s a search term that ended up at this website (most likely due to this post ) and I hate to disappoint visitors. According to WhatTheFont.com, the…</description><pubDate>Wed, 03 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Yep, that&apos;s a search term that ended up at this website (most likely due to &lt;a href=&quot;https://chrisk.io/matching-bazinga-shirts/&quot;&gt;this post&lt;/a&gt;) and I hate to disappoint visitors. According to WhatTheFont.com, the expression spouted by one Doctor Sheldon Cooper after someone falls victim to one of his &apos;ruses&apos; is written in &lt;strong&gt;Bada Boom Pro BB Italic&lt;/strong&gt;. I&apos;m not crazy, my mother had me tested... &lt;a href=&quot;http://www.myfonts.com/fonts/blambot/bada-boom-pro-bb/italic/&quot;&gt;http://www.myfonts.com/fonts/blambot/bada-boom-pro-bb/italic/&lt;/a&gt; There you go fellow internet traveler. I hope that helped out your mission today. Now go away, I&apos;ve got code to write.&lt;/p&gt;
&lt;p&gt;Here&apos;s your comparison, for science:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/b43b57646ab96b1de33a870e62a989.gif&quot;&gt;&lt;img src=&quot;/images/blog/b43b57646ab96b1de33a870e62a989.gif&quot; alt=&quot;b43b57646ab96b1de33a870e62a989&quot; /&gt;&lt;/a&gt; Tilt this a bit, adjust the kerning and it&apos;s a perfect match. &lt;a href=&quot;/images/blog/e5a4_bazinga_hoodie.jpg&quot;&gt;&lt;img src=&quot;/images/blog/e5a4_bazinga_hoodie-300x207.jpg&quot; alt=&quot;e5a4bazingahoodie&quot; /&gt;&lt;/a&gt; This image is copyright of the respected owners...CBS/Big Bang Theory, or something like that...I don&apos;t own it.&lt;/p&gt;
</content:encoded></item><item><title>Integrating Todo.txt with Gnome Do</title><link>https://chrisk.io/posts/integrating-todo-txt-gnome/</link><guid isPermaLink="true">https://chrisk.io/posts/integrating-todo-txt-gnome/</guid><description>I&apos;m a long time user of both Gnome DO and Todo.txt . Recently, I&apos;ve been looking for a good method of making these two work together in harmony and I&apos;ve…</description><pubDate>Thu, 21 Mar 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m a long time user of both &lt;a href=&quot;http://do.cooperteam.net/&quot;&gt;Gnome DO&lt;/a&gt; and &lt;a href=&quot;http://todotxt.com/&quot;&gt;Todo.txt&lt;/a&gt;. Recently, I&apos;ve been looking for a good method of making these two work together in harmony and I&apos;ve finally done so. I executed this on Ubuntu 12.10. This article assumes a couple things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You have Gnome Do setup and configured with the Gnome Terminal plugin&lt;/li&gt;
&lt;li&gt;You have Todo.txt fully working&lt;/li&gt;
&lt;li&gt;You have sudo access on the computer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The typical usage of Todo.txt is all command line or mobile app based (&lt;a href=&quot;https://chrisk.io/android-todotxt&quot;&gt;Android&lt;/a&gt; and &lt;a href=&quot;https://chrisk.io/ios-todotxt&quot;&gt;iOS&lt;/a&gt;). What I was looking for was a quick way to add, alter, complete, and delete entries without having to open a terminal. I searched a bit and found Gnome Shell extensions, but those don&apos;t work with the Unity interface of Ubuntu 12.10.&lt;/p&gt;
&lt;p&gt;Step 1: Symlink the todo.sh to /usr/bin&lt;br /&gt;
[bash light=true] $ sudo ln -s /path/to/your/todo/todo.sh /usr/bin/todo[/bash]&lt;/p&gt;
&lt;p&gt;Step 2: Symlink your todo.cfg to .config/todo/config&lt;br /&gt;
[bash light=true]$ sudo ln -s /path/to/your/todo/todo.cfg ~/.config/todo/config[/bash]&lt;/p&gt;
&lt;p&gt;These 2 steps are very important as the Gnome Terminal plugin for Gnome Do doesn&apos;t recognize todo.sh as a terminal program. These steps allow this to happen.&lt;/p&gt;
&lt;p&gt;Step 3: Enjoy Todo.txt from your Gnome DO interface!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/gnomedotodotxt.png&quot;&gt;&lt;img src=&quot;/images/blog/gnomedotodotxt-300x207.png&quot; alt=&quot;Gnome Do and Todo.txt playing together nicely.&quot; /&gt;&lt;/a&gt; Gnome Do and Todo.txt playing together nicely.&lt;/p&gt;
&lt;p&gt;The usage here is pretty simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Activate Gnome Do&lt;/li&gt;
&lt;li&gt;Type out your command (eg: todo add &quot;New Item @context +project&quot;)&lt;/li&gt;
&lt;li&gt;Hit the &apos;tab&apos; key once your full entry is typed&lt;/li&gt;
&lt;li&gt;Choose &apos;Run in Terminal&apos; (I use the arrow keys so I don&apos;t have to use the mouse)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This works with all commands of Todo.txt.&lt;/p&gt;
&lt;p&gt;When it comes to reading my Todo.txt list, I use a varity of methods including the iOS and Android Apps, as well as a &lt;a href=&quot;https://github.com/ginatrapani/todo.txt-cli/wiki/Linux-with-Conky&quot;&gt;Conky Configuration&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>My Perspective on Debugging</title><link>https://chrisk.io/posts/perspective-debugging/</link><guid isPermaLink="true">https://chrisk.io/posts/perspective-debugging/</guid><description>So earlier tonight I was doing some work for a client and fired off a Tweet in frustration. I&apos;ve embedded it below for easy of use:…</description><pubDate>Tue, 26 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So earlier tonight I was doing some work for a client and fired off a Tweet in frustration. I&apos;ve embedded it below for easy of use:&lt;/p&gt;
&lt;p&gt;https://twitter.com/cklosowski/status/306596185366482945&lt;/p&gt;
&lt;p&gt;The &apos;#ragequit&apos; was me just stopping work for a while, in frustration, and no, I don&apos;t think anyone should quit writing plugins, and no I won&apos;t list the plugin and in fact, I deleted the response in which I listed the name. I&apos;m doing this out of respect for the developers as I was so &lt;a href=&quot;https://twitter.com/zslabs/status/306608419991851009&quot;&gt;graciously reminded that we are all human&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of the major responses I got was, &quot;Why not just contribute and fix it?!&quot; and I&apos;m going to see if I can help out with that however, it did bring up a valid point...at what point are developers sometimes complacent with the code they release? I know we&apos;re all supposed to be &apos;Embarrassed by 1.0&apos;, but that doesn&apos;t mean &apos;Careless with 1.0&apos;.&lt;/p&gt;
&lt;p&gt;Developers who write code without display errors (or at least error reporting) turned on are only pulling the shades down to hide the crummy view. Notices and warnings are reminders that we&apos;re not quite doing it correctly, and should probably fix it. If your tooth hurts, you go to the dentist. If you have a cough, you go to the doctor. These are symptoms of underlying issues. Same goes with Warnings and Notices. They are symptoms that something isn&apos;t quite right and needs a fix. You can live with a sore tooth, or a cough, but life is so much better without them.&lt;/p&gt;
&lt;p&gt;As pointed out in a fairly lengthy StackOverflow response about &lt;a href=&quot;http://stackoverflow.com/questions/5073642/why-should-i-fix-e-notice-errors&quot;&gt;&quot;Why should I fix E_NOTICE Errors?&quot;&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;3. THE BEST REASON&lt;/p&gt;
&lt;p&gt;If you don&apos;t fix all the E_NOTICE errors that you think aren&apos;t errors, you will probably grow complacent, and start ignoring the messages, and then one day you when a real error happens, you won&apos;t notice it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In all the noise, it&apos;s hard to determine the real cause of any future errors. So developers of WordPress plugins, please use WP_DEBUG or at least do your users the favor of &lt;a href=&quot;https://twitter.com/tooshel/status/306609837570134016&quot;&gt;tailing the wpdebug log file&lt;/a&gt; as Sheldon McGee mentions.&lt;/p&gt;
&lt;p&gt;For one of the most straight forward and best resources for debugging information and tools specific to WordPress, check out the &lt;a href=&quot;http://codex.wordpress.org/Debugging_in_WordPress&quot;&gt;Debugging In WordPress Codex Page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now let&apos;s all go write some clean code!&lt;/p&gt;
&lt;p&gt;Featured Image via &lt;a href=&quot;http://www.flickr.com/photos/29233640@N07/3645211083/&quot;&gt;Flick, Creative Commons, and Robert Couse-Baker&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Postmeta all the things!</title><link>https://chrisk.io/posts/postmeta-things/</link><guid isPermaLink="true">https://chrisk.io/posts/postmeta-things/</guid><description>I decided it was time to update the theme for this site to something a little less...kid like? I dunno, it was growing old on me. I always typically just go…</description><pubDate>Mon, 11 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I decided it was time to update the theme for this site to something a little less...kid like? I dunno, it was growing old on me. I always typically just go through the basic featured themes on WordPress.org trying to find something that will suit my needs. I don&apos;t want to make it a labor of love...just somewhere I can post my thoughts. Anyway, I&apos;m digressing.&lt;/p&gt;
&lt;p&gt;I ended up on this nice looking, feature rich, responsive (need this) theme called &lt;a href=&quot;http://wordpress.org/extend/themes/pinboard&quot;&gt;Pinboard&lt;/a&gt;. Yep, it&apos;s a popular one, I&apos;m fine with that. I was having this weird issue where on posts imported from Flickr, a double image was showing, as well as some extra information about the Flickr URL. I decided to dive in.&lt;/p&gt;
&lt;p&gt;Turns out, this theme has a function that takes all post meta entries (custom fields) and displays them. Here&apos;s the code:&lt;/p&gt;
&lt;p&gt;&amp;lt;?php $meta_keys = get_post_meta( get_the_ID() ); ?&amp;gt;
&amp;lt;?php foreach( $meta_keys as $meta =&amp;gt; $value ) : ?&amp;gt;
&amp;lt;?php if( ( &apos;_&apos; != $meta[0] ) &amp;amp;&amp;amp; ( &apos;enclosure&apos; != $meta ) ) : ?&amp;gt;
&amp;lt;span class=&quot;custom-meta&quot;&amp;gt;&amp;lt;strong&amp;gt;&amp;lt;?php echo $meta; ?&amp;gt;:&amp;lt;/strong&amp;gt; &amp;lt;?php echo $value[0]; ?&amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;?php endif; ?&amp;gt;
&amp;lt;?php endforeach; ?&amp;gt;&lt;/p&gt;
&lt;p&gt;This was the cause of my problem. I was seeing entries made by the Flickr import, in my post meta area. I&apos;ve submitted a support ticket asking for a clarification as to why they would do this or if they&apos;d consider a filter on this. I&apos;ll update the post when I hear back.&lt;/p&gt;
&lt;p&gt;This is a bad idea for a few reasons, but most importantly, some plugins use this area to store non-user-facing information about the posts. Doing a blanket display of postmeta could result in some improperly formatted or private data being shown to users.&lt;/p&gt;
&lt;p&gt;Post image by &lt;a href=&quot;http://www.flickr.com/photos/motti82/3778598336/&quot;&gt;motti82&lt;/a&gt; via Flickr &amp;amp; Creative commons&lt;/p&gt;
</content:encoded></item><item><title>5 Things I&apos;ve Learned About Writing Flexible Plugins</title><link>https://chrisk.io/posts/5-learned-writing-flexible-plugins/</link><guid isPermaLink="true">https://chrisk.io/posts/5-learned-writing-flexible-plugins/</guid><description>This year I had the opportunity to travel to WordCamp San Francisco where I saw a myriad of great speakers and met a ton of great WordPress developers,…</description><pubDate>Tue, 05 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This year I had the opportunity to travel to WordCamp San Francisco where I saw a myriad of great speakers and met a ton of great WordPress developers, users, and everything in between. One of the most influential talks, for me at least, was by Michael Fields on &quot;Extendable Extensions&quot;. You can watch the video on WordPress.tv: &lt;a href=&quot;http://wordpress.tv/2012/08/27/michael-fields-extendable-extensions/&quot;&gt;http://wordpress.tv/2012/08/27/michael-fields-extendable-extensions/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So, after a while I started try and find ways I could include this in my plugins. Let me tell you, I&apos;ve never coded like this before. While attempting this, I&apos;ve started to realize how non-friendly my code was to other developers or people who wanted to change just the smallest detail about the output of my plugin. I was pretty pumped at this point to move forward and with Pushover Notifications for WordPress, I&apos;m living it. &lt;a href=&quot;https://wp-push.com/&quot;&gt;Pushover Notifications for WordPress&lt;/a&gt; is pretty extensible, and is getting more and more extensible with every release.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here&apos;s 5 things I&apos;ve started focusing on while writing my plugins to help make them more extensible.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;apply_filters All The Things!&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;apply_filters()&lt;/code&gt; is BY FAR the easiest way to make your code extendable. If your plugin displays text to a user and you can think of even 1 instance where someone might to change your verbiage, &lt;code&gt;apply_filters()&lt;/code&gt;. If you have an array of elements, and you think someone might want to add more to it at any point, &lt;code&gt;apply_filters()&lt;/code&gt;. This is a great tool, if you use it correctly. Don&apos;t just pass along the string or array you want to modify. The function also allows arguments to be passed. If you are modifying user data, send the user ID as an argument, if it&apos;s post content send the post ID. You get the point.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://codex.wordpress.org/Function_Reference/apply_filters&quot;&gt;Read more about apply_filters() in the codex.&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Make your admin menus extendable&lt;/h3&gt;
&lt;p&gt;I&apos;ve started putting &lt;code&gt;do_action()&lt;/code&gt; references to my settings pages and it&apos;s helped me realize that not only can someone change the content of your current settings, but they can add their own settings to your plugin. This is the next step in full extensible-ness. Without this, your plugin will eternally be just your plugin, nothing more, nothing less. Take it to the next level by putting in your own action hooks for people (or even yourself) to extend into.&lt;/p&gt;
&lt;h3&gt;Never assume your core plugin is available&lt;/h3&gt;
&lt;p&gt;If you&apos;ve already started doing the first two items I&apos;ve listed, then this is your most important take away. It&apos;s easy in our development sandboxes to think miss a real world scenario. I mean, who really would deactivate our one of our plugins that requires another?&lt;/p&gt;
&lt;p&gt;Well, users do, and as developers, it&apos;s our job to make sure we degrade gracefully. I failed this goal recently and let me tell you, it sucks. Use the &apos;function_exists&apos; and &apos;class_exists&apos; functions to verify the function or method you are about to use is available to you, prior to executing. Building plugins that work together can yield great results, just make sure you are yielding on the side of caution when relying on content from outside the core plugin.&lt;/p&gt;
&lt;p&gt;In my scenario, one of my extensions to Pushover Notifications for WordPress was calling a method in the core plugin looking for some settings. The error happened when the core plugin was being upgraded through the WordPress automatic updater. For a brief moment, my core plugin was unavailable while the changes were being applied, which caused my extension to return a server 500 error, halting the upgrade and corrupting the core plugin. How am I preventing it now? I&apos;m avoiding calls to the core plugin, and running function_exists checks prior to any calls to the core plugin.&lt;/p&gt;
&lt;h3&gt;Everybody wants a Log&lt;/h3&gt;
&lt;p&gt;Some of you may not &lt;a href=&quot;http://www.youtube.com/watch?v=eusMzC7Rx7M&quot;&gt;get that reference&lt;/a&gt;, but the phrase &quot;It&apos;s better than bad, it&apos;s Good&quot; is oh so true. If you are building something for every day use by others, build in the option for logging functionality. It makes it easier for you to troubleshoot errors in development but also makes your user&apos;s feedback more valuable. If you don&apos;t quite know how to start with logging, try out &lt;a href=&quot;http://pippinsplugins.com/wp-logging/&quot;&gt;Pippin&apos;s Plugins WP_Logging General Logging Class for WordPress&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Be embarassed by 1.0&lt;/h3&gt;
&lt;p&gt;There&apos;s a famous Opbeat Engineering quote that&apos;s slightly uncouth but goes something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;F*** It, Ship It&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since we&apos;re talking WordPress here, let&apos;s look at a slightly more classy rendition of the same principal, courtesy of Ma.tt (Matt Mullenweg):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;...if you’re not embarrassed when you ship your first version you waited too long.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You&apos;re going to have mistakes, unknown conflicts, and in some cases failure. That&apos;s part of learning and executing. Failure is always an option, but that&apos;s not a bad thing. Ship early, ship often, and never stop creating. The only thing better than getting your first bug report, is closing your first bug report as fixed. Also, bug reports mean people are using your product. Think of it that way.&lt;/p&gt;
&lt;p&gt;I know this got a little long winded and probably isn&apos;t as technical as some people may want, but these are the 5 key points I&apos;ve been trying to keep in my mind while working on my latest batch of extensions and it&apos;s really helped change my mindset on how I write my code.&lt;/p&gt;
&lt;p&gt;Post Image via Flickr &amp;amp; Creative Commons by &lt;a href=&quot;http://www.flickr.com/photos/7552532@N07/449769140/&quot;&gt;ATOMIC Hot Links&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Why Building Plugins for Others can be Hard</title><link>https://chrisk.io/posts/building-plugins-hard/</link><guid isPermaLink="true">https://chrisk.io/posts/building-plugins-hard/</guid><description>For those who don&apos;t know, I&apos;ve been developing WordPress plugins for about 5 years. While it started out as some random small time stuff, it&apos;s recently…</description><pubDate>Wed, 16 Jan 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;For those who don&apos;t know, I&apos;ve been developing WordPress plugins for about 5 years. While it started out as some random small time stuff, it&apos;s recently increased in scale with the release of &lt;a href=&quot;http://wp-push.com&quot;&gt;Pushover Notifications for WordPress&lt;/a&gt;. All of my plugins, including Pushover Notifications for WordPress were built because I found a need in WordPress and decided to fulfill it. This is a great method of development because you are the user and the developer. A great combination when it comes to bugs, features, user experience, etc.&lt;/p&gt;
&lt;p&gt;So shortly after the release of Pushover Notifications for WordPress, I got hit up by Adam Pickering (of &lt;a href=&quot;http://www.mintthemes.com/&quot;&gt;MintThemes.com&lt;/a&gt;) to possibly develop an extension for &lt;a href=&quot;https://easydigitaldownloads.com/&quot;&gt;Easy Digital Downloads&lt;/a&gt; (by &lt;a href=&quot;http://pippinsplugins.com/&quot;&gt;Pippin Williamson&lt;/a&gt;). There&apos;s a nice revenue sharing model with Easy Digital Downloads and it seemedd simple enough so away I went, coding up an integration of our two plugins.&lt;/p&gt;
&lt;p&gt;Here we are, a couple months later, and up until today, I&apos;ve never used Easy Digital Downloads on a live site with my extension, just a development environment. If you aren&apos;t in software development, let me be the first to mention that having a development environment exactly replicate a production site isn&apos;t 100% possible sometimes, even less when your plugin is used on a platform like WordPress. You have to write flexible code, and sometimes, we fail.&lt;/p&gt;
&lt;p&gt;Besides that, developing a plugin (or any application for that matter) when you aren&apos;t a user can be extremely difficult, even more so when it involves a purchase path (payment gateways and what not). I&apos;ve never realized the needs, wants, and annoyances of my work until I actually used it this week. I&apos;ve never noticed little things that other users probably curse my name at.&lt;/p&gt;
&lt;p&gt;So why write about this now? Well, like I said, I finally released WP-Push.com and with it, my first paid extension that I&apos;m hosting and selling, &lt;a href=&quot;http://wp-push.com/extensions/bbpress-extension/&quot;&gt;Pushover Notifications for bbPress&lt;/a&gt;. Today, seeing that first push notification of an actual sale (not just a test sale worth nothing), seeing my first sales report with real money in it, watching a new user signup...it all just clicked! I finally saw what my users found so exciting about the hard work I had done.&lt;/p&gt;
&lt;p&gt;While every application you develop may not be one you can use personally, I would implore you to build a personal relationship with some of your more active users. People who are able to give good feedback and can steer the direction of your (but in reality &lt;em&gt;their&lt;/em&gt;) product will be more valuable than you can imagine. If you can become an end user, there&apos;s nothing quite like seeing all those things people requested work right in front of you in a live environment.&lt;/p&gt;
&lt;p&gt;Post Image by &lt;a href=&quot;http://www.flickr.com/photos/kiler129/6390464879/&quot;&gt;Killer129&lt;/a&gt; under Creative Commons&lt;/p&gt;
</content:encoded></item><item><title>Matching Bazinga Shirts</title><link>https://chrisk.io/posts/matching-bazinga-shirts/</link><guid isPermaLink="true">https://chrisk.io/posts/matching-bazinga-shirts/</guid><description>I ended up getting a onsie for our baby Boy while in vacation and figured, for my birthday it was only fitting to get a matching shirt for myself. Jill and…</description><pubDate>Tue, 18 Dec 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://kungfugrep.wpengine.com/wp-content/uploads/2012/12/20121218-213604.jpg&quot;&gt;&lt;img src=&quot;http://kungfugrep.wpengine.com/wp-content/uploads/2012/12/20121218-213604.jpg&quot; alt=&quot;20121218-213604.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I ended up getting a onsie for our baby Boy while in vacation and figured, for my birthday it was only fitting to get a matching shirt for myself.&lt;/p&gt;
&lt;p&gt;Jill and I are going to plan a photo shoot once he can fit into it.&lt;/p&gt;
</content:encoded></item><item><title>Our Day in NOLA</title><link>https://chrisk.io/posts/day-nola/</link><guid isPermaLink="true">https://chrisk.io/posts/day-nola/</guid><description>So Jill and I decided to spend a day in the French Quarter, seeing as though we leave for the cruise tomorrow morning. We knew the Bayou Classic was in town…</description><pubDate>Sat, 24 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So Jill and I decided to spend a day in the French Quarter, seeing as though we leave for the cruise tomorrow morning. We knew the Bayou Classic was in town and started at 1pm so we delayed our trip slightly to try and avoid the mass hysteria of College Football Rivalries. After not being able to find the bus stop due to the lack of sign, we decided the 2.2 mile hike isn&apos;t too bad to hoof it (turns out the trip there wasn&apos;t so bad, it was the trip back that was the pain).&lt;/p&gt;
&lt;p&gt;After our stroll down to the Riverwalk Shopping Plaza we wound up looking for a souvenir Christmas ornaments in some holiday theme shop. Oddly enough, there was a ton of U of M gear along with the mass of LSU stuff. Oddly enough, very few Buckeyes, which we were OK with.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-2.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-2-224x300.jpg&quot; alt=&quot;&quot; title=&quot;U of M Christmas Ornimates&quot; /&gt;&lt;/a&gt; At least there were no OU Nut crackers.&lt;/p&gt;
&lt;p&gt;Near the end of the Riverwalk we found this amazing little comic book shop called &quot;Red Rocket Comics&quot;. Now, we may have only walked out with a Onise and a few laughs, but this place is legit. The guy working knew his stuff too. I had a hard time not spending a lot of time and money in this place. We did find this &apos;Bazinga!&apos; onsie and also a onsie that we figured was not a great idea to give your own child.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-13.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-13-224x300.jpg&quot; alt=&quot;&quot; title=&quot;Bazinga Onsie&quot; /&gt;&lt;/a&gt; Our child will be the coolest kid ever with this.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-3.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-3-224x300.jpg&quot; alt=&quot;&quot; title=&quot;Support Red Onsie&quot; /&gt;&lt;/a&gt; If you put your child in this, you have some questions to answer.&lt;/p&gt;
&lt;p&gt;After what seemed to be forever, we started to get a little hungry. By a little, I mean HUNGRY. We were headed the direction (or so I thought) of Café Du Monde, over in the French Quarter French Market area. Once I choose the correct location for Apple Maps to direct me to, we were truly on our way. I wish I had an actual picture of the beignets that we got, but they didn&apos;t actually last long. Let&apos;s just say they were the perfect little squares of deep fried, golden brown, powdered sugar covered, dough you can ever imagine. I did get a shot of the To Go Order line. It wrapped around the side of the building, and was about 15 minutes long. Yep, they are that good. At about $3 for 3 beignets, it&apos;s well worth the wait and cost.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-4.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-4-224x300.jpg&quot; alt=&quot;&quot; title=&quot;Cafe Du Monde&quot; /&gt;&lt;/a&gt; Today I discovered beignets.&lt;/p&gt;
&lt;p&gt;After we grabbed our food and ate on a bench along Decatur St. we strolled down into the Art District and French Market.&lt;/p&gt;
&lt;p&gt;The atmosphere here is kind of interesting as it&apos;s a mixture of restaurants that have walk up bars, a farmers market, some art shops, some gift shops, and a few locations that I wasn&apos;t really sure what they did, but wasn&apos;t about to go in to find out. Seeing people openly walk around with a beer was a little strange at first, but as it&apos;s frequent you get used to it.&lt;/p&gt;
&lt;p&gt;We had already figured out what we wanted to do for dinner, so we were going to grab lunch while we were here. We walked around a block that had a Margaritaville, thinking that could be our last resort. Jill spotted the Louisiana Pizza Kitchen and suggested it as we didn&apos;t quite get to fulfill my pizza craving from the prior night (or every night since I love pizza).&lt;/p&gt;
&lt;p&gt;The place is small just like everything else there. I asked our waiter to suggest one of the local beers on the menu and he recommended the Abita Winter Ale. It was great. Honestly better than any mass market Winter Ale I&apos;ve ever had and half the cost. Win, win. To test any pizza place I always just get their plain cheese. Great choice as their cheese was fantastic.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-6.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-6-224x300.jpg&quot; alt=&quot;&quot; title=&quot;Louisiana Pizza Kitchen&quot; /&gt;&lt;/a&gt; &quot;A delicious cheese pizza, just for me.&quot; - Kevin McAlister&lt;/p&gt;
&lt;p&gt;After pizza it was time to start heading back to the hotel and grab dinner to go on the way. Dinner is a sandwich called the &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Muffuletta&quot;&gt;Muffuletta&lt;/a&gt;&quot;. I can&apos;t do it justice, just click that link and you&apos;ll see what I mean. It&apos;s currently in the fridge, waiting to be devoured by us. The place that claims to have the &quot;original muffuletta&quot; is a place called Central Grocery on Decatur St. It&apos;s a classic grocery store with wooden shelves and what looks like product that&apos;s been on the shelf for 50 years.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-7.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-7-224x300.jpg&quot; alt=&quot;&quot; title=&quot;Central Grocery&quot; /&gt;&lt;/a&gt; The Original.&lt;/p&gt;
&lt;p&gt;After that was a 2 mile walk home and along it we saw some interesting shops, interesting people, and amazing old architecure, including old St. Patrick&apos;s church on Camp. The bells kept ringing in the bell tower and because of the buildings around it just echoed, and echoed, and echoed. It was hard to tell if it was the echo or the actual bells at times.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-10.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-10-224x300.jpg&quot; alt=&quot;&quot; title=&quot;St. Patrick&apos;s&quot; /&gt;&lt;/a&gt; Looking up at the bell tower of St. Patrick&apos;s.&lt;/p&gt;
&lt;p&gt;So that was our day in the French Quarter. We walked a lot and saw some amazing places. Here&apos;s some more pictures I grabbed while waking around.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-12.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-12-300x224.jpg&quot; alt=&quot;&quot; title=&quot;Old Building #1&quot; /&gt;&lt;/a&gt; A carriage house looking building that I found interesting.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-11.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-11-224x300.jpg&quot; alt=&quot;&quot; title=&quot;Intersting Building #2&quot; /&gt;&lt;/a&gt; This home was across from St. Patrick&apos;s. I don&apos;t think I could handle the bells.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-9.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-9-224x300.jpg&quot; alt=&quot;&quot; title=&quot;Canal Street&quot; /&gt;&lt;/a&gt; Looking down Canal Street.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-8.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-8-224x300.jpg&quot; alt=&quot;&quot; title=&quot;Old Sign&quot; /&gt;&lt;/a&gt; An old advertisement painted on the side of a shop on Decatur.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/Photo-5.jpg&quot;&gt;&lt;img src=&quot;/images/blog/Photo-5-224x300.jpg&quot; alt=&quot;&quot; title=&quot;French Market Galleries&quot; /&gt;&lt;/a&gt; The Art Gallery area of the French Market.&lt;/p&gt;
</content:encoded></item><item><title>Quick and Easy Google Analytics with Social Interaction Tracking</title><link>https://chrisk.io/posts/quick-easy-google-analytics-social-interaction-tracking/</link><guid isPermaLink="true">https://chrisk.io/posts/quick-easy-google-analytics-social-interaction-tracking/</guid><description>I&apos;ve been trying to find a good social interaction tracking Google Analytics Plugin but they&apos;ve all been heavier than I wanted them to be. So I decided to…</description><pubDate>Mon, 19 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been trying to find a good social interaction tracking Google Analytics Plugin but they&apos;ve all been heavier than I wanted them to be. So I decided to make my own. Here&apos;s a link to my &quot;Site Specific Analytics&quot; tracking plugin. You need to edit the &lt;code&gt;ga.js&lt;/code&gt; file and replace the string &lt;code&gt;UA-xxxxxxx-xx&lt;/code&gt; with the Google Analytics code for your site. The JavaScript is minified so you should be good to go.&lt;/p&gt;
&lt;p&gt;Other than that, nothing else is needed other than activation. Cheers&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/cklosowski/site-specific-analytics&quot;&gt;Site Specific Analytics on GitHub&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Why I Ditch the Laptop During Conference Tracks</title><link>https://chrisk.io/posts/ditch-laptop-conference-tracks/</link><guid isPermaLink="true">https://chrisk.io/posts/ditch-laptop-conference-tracks/</guid><description>So tomorrow is Desert Code Camp 2012, and with it comes my first public appearance as a speaker. I&apos;ll be doing a track on &quot;WordPress Plugin Bootcamp&quot; where…</description><pubDate>Fri, 16 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So tomorrow is Desert Code Camp 2012, and with it comes my first public appearance as a speaker. I&apos;ll be doing a track on &quot;WordPress Plugin Bootcamp&quot; where I talk about the conventions and steps it takes to build your own plugin for WordPress. While I&apos;m a presenter for 1 session, I&apos;ll be busy during every other time slot as an attendee. With that, comes notes and ideas. One thing I&apos;ve found though is that the laptop, considered the note taking wonder of the world, hinders the amount of information I can absorb and digest.&lt;/p&gt;
&lt;p&gt;I think attendees should drop the laptop/netbook/iPad/tablet and switch it out for...good ole&apos; pen and paper. If you are thinking it&apos;s because I&apos;m a presenter and I don&apos;t want you playing Farmville while I&apos;m trying to drop knowledge on you, you&apos;d be wrong. Pen and Paper notes have 3 distinct advantages over note taking on your little internet box.&lt;/p&gt;
&lt;h3&gt;You aren&apos;t distracted.&lt;/h3&gt;
&lt;p&gt;There are no notifications in your little notebook. No Emails, no IMs, no flashing little icons. Just you, your pen, your paper, and the presenter. This allows you to focus on them instead of the distraction in front of you.&lt;/p&gt;
&lt;h3&gt;You can draw.&lt;/h3&gt;
&lt;p&gt;And I don&apos;t mean stick figures...unless the presenter has a diagram of stick figures. Then it&apos;s ok. With pen and paper you are able to freely diagram anything in the slides. You can link items together with arrows. The list goes on. The basics are you can freely and openly make marks.&lt;/p&gt;
&lt;h3&gt;You can make eye contact.&lt;/h3&gt;
&lt;p&gt;Ok, this one is more about the presenter...but in a way that will affect you. When presenting, it&apos;s easier to get a gauge of your audience and if they are keeping up when you can see their eyes. If they are busy staring at their screens, it&apos;s difficult to see if they are right with you, or if they glossed over 5 slides ago and are giving up to play hearts. A good presentation is a 2 way street and non-verbal communication can make it better.&lt;/p&gt;
&lt;p&gt;So I urge you, if you are attending a conference and feel the urge to take notes, bust out that pen and paper and see if it helps you have a more immersible experience.&lt;/p&gt;
&lt;p&gt;If you want to see my slides from the presentation you can view them &lt;a href=&quot;http://x.co/DCC12WPBC&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>The Gender Reveal Process</title><link>https://chrisk.io/posts/the-gender-reveal-process/</link><guid isPermaLink="true">https://chrisk.io/posts/the-gender-reveal-process/</guid><description>So there have been a few discussions about how we&apos;re going to reveal the gender of our baby. First, how we want to find out. Second, how we&apos;re going to…</description><pubDate>Wed, 24 Oct 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So there have been a few discussions about how we&apos;re going to reveal the gender of our baby. First, how we want to find out. Second, how we&apos;re going to reveal to family and friends. I&apos;ll disclose how we&apos;re going to inform ourselves, but as far as the family and friends go, we&apos;ll leave that to a surprise. So here&apos;s the plan I devised and that Jill is going along with.&lt;/p&gt;
&lt;h3&gt;Setup&lt;/h3&gt;
&lt;p&gt;Our ultrasound appointment for learning the gender is November 21st. That&apos;s 2 days before we leave on vacation, and 4 days from when our cruise sets sail for &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Babymoon&quot;&gt;Babymoon&lt;/a&gt; 2012&quot;.&lt;/p&gt;
&lt;h3&gt;The Plan&lt;/h3&gt;
&lt;p&gt;Going against everything my body will be telling me, we&apos;re going to attempt to not see the gender in the ultrasound and have the tech write the gender in an envelope, and seal it. Then we&apos;ll bring it on vacation with us. We will make all attempts to not open this envelope until we hand it off to the waitstaff during our first meal on the cruise. Our request will be that it arrives as part of our dessert that night (weather it just be the card, or a special plating disclosing the gender).&lt;/p&gt;
&lt;p&gt;So that&apos;s how we&apos;re going to &lt;em&gt;try&lt;/em&gt; and do it. As for the rest of you who are expecting the family &amp;amp; friends reveal, you&apos;ll just have to wait and see our plan for that.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Theres only 176 days until we get to meet you. I don&apos;t think I&apos;ve ever been so nervous and excited at the same time. If you ask your mom, I&apos;ve probably read more in the last 3 months than through my entire college and high school careers combined.&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>3 Things I&apos;ve Learned Developing for an Open Source platform</title><link>https://chrisk.io/posts/3-things-ive-learned-developing-for-an-open-source-platform/</link><guid isPermaLink="true">https://chrisk.io/posts/3-things-ive-learned-developing-for-an-open-source-platform/</guid><description>This year marks 7 years that I&apos;ve been developing plugins for WordPress, and 3 years that I&apos;ve been doing software development as a day job. I could go on…</description><pubDate>Wed, 03 Oct 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This year marks 7 years that I&apos;ve been developing plugins for WordPress, and 3 years that I&apos;ve been doing software development as a day job. I could go on and on about what I&apos;ve learned over the past 7 years. I&apos;ve read countless books, blog posts, and articles ranging from topics of SDLC, Development Styles, Coding standards, and career planning. All of that is great and all, but there are 3 things I&apos;ve learned developing for an open source platform (namely WordPress) that I think produce the best end product.&lt;/p&gt;
&lt;h3&gt;1. What your users want is important, but not the most important&lt;/h3&gt;
&lt;p&gt;Yes, your users are your customers when it comes to Open Source. They will have suggestions, fixes, improvements, and other input on what you should do differently or next with your project. All my projects started out as something I wanted myself, that I figured some other people could use. From there you publish your project and the feature requests start pouring in (along with the bug reports). Where do you go from here?&lt;/p&gt;
&lt;p&gt;The truth is, nothing is free. While you aren&apos;t being paid, you are using your free time to develop the project. Keep yourself (and your significant other/family/friends) happy/healthy before you put your project first. I&apos;ve made that mistake a few times. In the middle of date night is not the time to respond to a bug report. Just trust me on that one. Take all input from your users seriously, but also keep your expectations realistic.&lt;/p&gt;
&lt;h3&gt;2. Take everything your users say seriously&lt;/h3&gt;
&lt;p&gt;Hot on the heels of the first thing, you have to listen to your users and no matter how &quot;stupid&quot; you think the request or bug is, this person thought it was important enough to tell you. Some users may not be developers, some may be great developers. The point is, if someone takes the time to fill out a report or feature request, you should take the time to read it and give it a chance for consideration. Without your users, your app/project is nothing.&lt;/p&gt;
&lt;h3&gt;3. Get and give feedback&lt;/h3&gt;
&lt;p&gt;One of my favorite parts of open source development is the community. Particularly in the WordPress community, there is a wealth of knowledge in software development practices and skills that any fortune 500 company would die for. The catch, most of these people volunteer their time to the project, and are basically willing to give you feedback for free. If you feel you have knowledge in an area, give a little back. It&apos;s a self-sufficient system where users help users and developers help developers and the end product is a well oiled machine of productivity.&lt;/p&gt;
&lt;p&gt;Like I&apos;ve said, I&apos;ve learned WAY more than 3 things but these are ones that I think have become my focus in the past 6-8 months. Hopefully I can keep up with the feedback and listening to my users, while balancing my home life. Challenge: Accepted.&lt;/p&gt;
&lt;p&gt;[image credit: &lt;a href=&quot;http://www.confluex.com/&quot;&gt;http://www.confluex.com/&lt;/a&gt;]&lt;/p&gt;
</content:encoded></item><item><title>Apache2 vhost_combined log files</title><link>https://chrisk.io/posts/apache2-vhost-combined-log-files/</link><guid isPermaLink="true">https://chrisk.io/posts/apache2-vhost-combined-log-files/</guid><description>How to define a vhost_combined log format to combine Apache logs for all vhosts into a single log file.</description><pubDate>Tue, 10 Apr 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently I&apos;ve been fighting with memory consumption on my server and have been looking for ways that I can reduce the overall load. After some research I found that Apache opens up a file descriptor for each VHosts log file, and keeps this descriptor open all the time. So when I had a bunch of sites that I didn&apos;t mind if their log files were combined, I did some work by using the vhost_combined logging format, which groups a set of vhosts into a single log file. I verified that first, my /etc/apache2/apache2.conf file had a CustomLog entry for vhost_combined:&lt;/p&gt;
&lt;p&gt;LogFormat &quot;%v:%p %h %l %u %t &quot;%r&quot; %&amp;gt;s %O &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot;&quot; vhost_combined&lt;/p&gt;
&lt;p&gt;Once this was confirmed I went into each of the config files in the sites-available directory and modified a single line:&lt;/p&gt;
&lt;p&gt;CustomLog /var/log/apache2/groupofsites-access.log vhost_combined&lt;/p&gt;
&lt;p&gt;Notice that I added that &apos;vhost_combined&apos; to the end of this line, meaning that it will use the log format from above and for each vhost assigned to use this log file, only keep 1 file descriptor open instead of 6. So far I&apos;ve actually noticed a quicker response from my webserver as well as lower memory usage. Hopefully this helps you out as well!&lt;/p&gt;
&lt;p&gt;If you&apos;re searching for a hosting provider, I recommend &lt;a href=&quot;https://chrisk.io/chunkhost&quot;&gt;ChunkHost&lt;/a&gt;. They have great uptime, a very responsive support staff, and their prices are hard to beat. See &lt;a href=&quot;https://chrisk.io/hosting-review-chunkhost-vps/&quot;&gt;my review of ChunkHost&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>The Conversion is complete</title><link>https://chrisk.io/posts/the-conversion-is-complete/</link><guid isPermaLink="true">https://chrisk.io/posts/the-conversion-is-complete/</guid><description>If you were visiting this blog to get some Linux How To&apos;s and stuff, You&apos;ll find some of those still. However, starting today I&apos;m converting this into my…</description><pubDate>Fri, 27 Jan 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you were visiting this blog to get some Linux How To&apos;s and stuff, You&apos;ll find some of those still. However, starting today I&apos;m converting this into my personal blog. I&apos;m a PHP Software Developer who has stuff to talk about apparently. I&apos;ll be blogging personally here from now on, but in my world, personally means it&apos;ll still include some Geeky outlets of code, hacks, and stuff of the likes.&lt;/p&gt;
</content:encoded></item><item><title>Customizing your .vimrc file</title><link>https://chrisk.io/posts/customizing-vimrc-file/</link><guid isPermaLink="true">https://chrisk.io/posts/customizing-vimrc-file/</guid><description>If you are using Linux and haven&apos;t familiarized yourself with the world of VIM yet...then you need to rethink your text editing habits. Alright, so that&apos;s a…</description><pubDate>Wed, 20 Jul 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you are using Linux and haven&apos;t familiarized yourself with the world of VIM yet...then you need to rethink your text editing habits. Alright, so that&apos;s a little harsh, but did you know that with a few changes to your .vimrc file (stored in your home directory) you can mold VIM into a very powerful Integrated Development Environment (IDE)?! Then if you stack on a few plugins like &apos;Nerd Tree&apos; and &apos;Exuberant C-Tags&apos; you have an development environment that rivals any paid application.&lt;/p&gt;
&lt;p&gt;Here are a few of my favorites:&lt;/p&gt;
&lt;p&gt;&quot; First turn on the plugins for the tabs and syntax highlighting
&quot; Enable loading filetype and indentation plugins
filetype plugin on
filetype indent on&lt;/p&gt;
&lt;p&gt;&quot; Turn syntax highlighting on&lt;br /&gt;
syntax on&lt;/p&gt;
&lt;p&gt;&quot; Use 2 spaces for (auto)indent&lt;br /&gt;
set shiftwidth=2&lt;/p&gt;
&lt;p&gt;&quot; Don&apos;t highlight results of a search&lt;br /&gt;
set nohlsearch&lt;/p&gt;
&lt;p&gt;&quot; When a bracket is inserted, briefly jump to a matching one&lt;br /&gt;
set showmatch&lt;/p&gt;
&lt;p&gt;Here&apos;s a full text copy of my .vimrc file. Keep in mind I have Exuberant C-Tags, Omni-Complete and Nerd Tree also in use so those are in my mappings.&lt;/p&gt;
&lt;p&gt;&quot;
&quot; MAIN CUSTOMIZATION FILE
&quot;&lt;/p&gt;
&lt;p&gt;&quot; Enable loading filetype and indentation plugins&lt;br /&gt;
filetype plugin on&lt;br /&gt;
filetype indent on&lt;/p&gt;
&lt;p&gt;&quot; Turn syntax highlighting on&lt;br /&gt;
syntax on&lt;/p&gt;
&lt;p&gt;&quot;&lt;br /&gt;
&quot; GLOBAL SETTINGS&lt;br /&gt;
&quot;&lt;br /&gt;
&quot; Define Color scheme&lt;br /&gt;
color delek&lt;/p&gt;
&lt;p&gt;&quot; Write contents of the file, if it has been modified, on buffer exit&lt;br /&gt;
set autowrite&lt;/p&gt;
&lt;p&gt;&quot; Allow backspacing over everything&lt;br /&gt;
set backspace=indent,eol,start&lt;/p&gt;
&lt;p&gt;&quot; Insert mode completion options&lt;br /&gt;
set completeopt=menu,longest,preview&lt;/p&gt;
&lt;p&gt;&quot; Use UTF-8 as the default buffer encoding&lt;br /&gt;
set enc=utf-8&lt;/p&gt;
&lt;p&gt;&quot; Remember up to 100 &apos;colon&apos; commmands and search patterns&lt;br /&gt;
set history=100&lt;/p&gt;
&lt;p&gt;&quot; Enable incremental search&lt;br /&gt;
set incsearch&lt;/p&gt;
&lt;p&gt;&quot; Always show status line, even for one window&lt;br /&gt;
set laststatus=2&lt;/p&gt;
&lt;p&gt;&quot; Jump to matching bracket for 2/10th of a second (works with showmatch)&lt;br /&gt;
set matchtime=2&lt;/p&gt;
&lt;p&gt;&quot; Don&apos;t highlight results of a search&lt;br /&gt;
set nohlsearch&lt;/p&gt;
&lt;p&gt;&quot; Enable CTRL-A/CTRL-X to work on octal and hex numbers, as well as characters&lt;br /&gt;
set nrformats=octal,hex,alpha&lt;/p&gt;
&lt;p&gt;&quot; Use F10 to toggle &apos;paste&apos; mode&lt;br /&gt;
set pastetoggle=&amp;lt;f10&amp;gt;&lt;/p&gt;
&lt;p&gt;&quot; Show line, column number, and relative position within a file in the status line&lt;br /&gt;
set ruler&lt;/p&gt;
&lt;p&gt;&quot; Scroll when cursor gets within 3 characters of top/bottom edge&lt;br /&gt;
set scrolloff=3&lt;/p&gt;
&lt;p&gt;&quot; Round indent to multiple of &apos;shiftwidth&apos; for &amp;gt; and &amp;lt; commands&lt;br /&gt;
set shiftround&lt;/p&gt;
&lt;p&gt;&quot; Use 4 spaces for (auto)indent&lt;br /&gt;
set shiftwidth=2&lt;/p&gt;
&lt;p&gt;&quot; Show (partial) commands (or size of selection in Visual mode) in the status line&lt;br /&gt;
set showcmd&lt;/p&gt;
&lt;p&gt;&quot; When a bracket is inserted, briefly jump to a matching one&lt;br /&gt;
set showmatch&lt;/p&gt;
&lt;p&gt;&quot; Don&apos;t request terminal version string (for xterm)&lt;br /&gt;
set t_RV=&lt;/p&gt;
&lt;p&gt;&quot; Use 2 spaces for &amp;lt;tab&amp;gt; and :retab&lt;br /&gt;
set tabstop=2&lt;/p&gt;
&lt;p&gt;&quot; Write swap file to disk after every 50 characters&lt;br /&gt;
set updatecount=50&lt;/p&gt;
&lt;p&gt;&quot; Remember things between sessions&lt;br /&gt;
&quot;&lt;br /&gt;
&quot; &apos;20  - remember marks for 20 previous files&lt;br /&gt;
&quot; &quot;50 - save 50 lines for each register&lt;br /&gt;
&quot; :20  - remember 20 items in command-line history&lt;br /&gt;
&quot; %    - remember the buffer list (if vim started without a file arg)&lt;br /&gt;
&quot; n    - set name of viminfo file&lt;br /&gt;
set viminfo=&apos;20,&quot;50,:20,%,n~/.viminfo&lt;/p&gt;
&lt;p&gt;&quot; Use menu to show command-line completion (in &apos;full&apos; case)&lt;br /&gt;
set wildmenu&lt;/p&gt;
&lt;p&gt;&quot; Set command-line completion mode:&lt;br /&gt;
&quot;   - on first &amp;lt;tab&amp;gt;, when more than one match, list all matches and complete&lt;br /&gt;
&quot;     the longest common  string&lt;br /&gt;
&quot;   - on second &amp;lt;tab&amp;gt;, complete the next full match and show menu&lt;br /&gt;
set wildmode=list:longest,full&lt;/p&gt;
&lt;p&gt;&quot; Go back to the position the cursor was on the last time this file was edited&lt;br /&gt;
au BufReadPost * if line(&quot;&apos;&quot;&quot;) &amp;gt; 0 &amp;amp;&amp;amp; line(&quot;&apos;&quot;&quot;) &amp;lt;= line(&quot;$&quot;)|execute(&quot;normal `&quot;&quot;)|endif&lt;/p&gt;
&lt;p&gt;&quot; Fix my &amp;lt;backspace&amp;gt; key (in Mac OS X Terminal)&lt;br /&gt;
set t_kb=&lt;br /&gt;
fixdel&lt;/p&gt;
&lt;p&gt;&quot; Avoid loading MatchParen plugin&lt;br /&gt;
let loaded_matchparen = 1&lt;/p&gt;
&lt;p&gt;&quot; netRW: Open files in a split window&lt;br /&gt;
let g:netrw_browse_split = 1&lt;/p&gt;
&lt;p&gt;&quot;&lt;br /&gt;
&quot; MAPPINGS&lt;br /&gt;
&quot;&lt;/p&gt;
&lt;p&gt;&quot; save changes&lt;br /&gt;
map ,s :w&amp;lt;cr&amp;gt;&lt;br /&gt;
&quot; exit vim without saving any changes&lt;br /&gt;
map ,q :q!&amp;lt;cr&amp;gt;&lt;br /&gt;
&quot; exit vim saving changes&lt;br /&gt;
map ,w :x&amp;lt;cr&amp;gt;&lt;br /&gt;
&quot; switch to upper/lower window quickly&lt;br /&gt;
map &amp;lt;c-J&amp;gt; &amp;lt;c-W&amp;gt;j&lt;br /&gt;
map &amp;lt;c-K&amp;gt; &amp;lt;c-W&amp;gt;k&lt;br /&gt;
&quot; use CTRL-F for omni completion&lt;br /&gt;
imap &amp;lt;c-F&amp;gt;&lt;br /&gt;
&quot; map CTRL-L to piece-wise copying of the line above the current one&lt;br /&gt;
imap &amp;lt;c-L&amp;gt; @@@&amp;lt;esc&amp;gt;hhkywjl?@@@&amp;lt;cr&amp;gt;P/@@@&amp;lt;cr&amp;gt;3s&lt;br /&gt;
&quot; map ,f to display all lines with keyword under cursor and ask which one to&lt;br /&gt;
&quot; jump to&lt;br /&gt;
nmap ,f [I:let nr = input(&quot;Which one: &quot;)&amp;lt;bar&amp;gt;exe &quot;normal &quot; . nr .&quot;[t&quot;&amp;lt;cr&amp;gt;&lt;br /&gt;
&quot; use &amp;lt;f6&amp;gt; to toggle line numbers&lt;br /&gt;
nmap &amp;lt;silent&amp;gt; &amp;lt;f6&amp;gt; :set number!&amp;lt;cr&amp;gt;&lt;br /&gt;
&quot; page down with &amp;lt;space&amp;gt;&lt;br /&gt;
nmap &amp;lt;space&amp;gt; &amp;lt;pageDown&amp;gt;&lt;br /&gt;
&quot; open filename under cursor in a new window (use current file&apos;s working&lt;br /&gt;
&quot; directory)&lt;br /&gt;
nmap gf :new %:p:h/&amp;lt;cfile&amp;gt;&amp;lt;cr&amp;gt;&lt;br /&gt;
&quot; map &amp;lt;alt-p&amp;gt; and &amp;lt;alt-P&amp;gt; to paste below/above and reformat&lt;br /&gt;
nnoremap &amp;lt;esc&amp;gt;P  P&apos;[v&apos;]=&lt;br /&gt;
nnoremap &amp;lt;esc&amp;gt;p  p&apos;[v&apos;]=&lt;br /&gt;
&quot; visual shifting (does not exit Visual mode)&lt;br /&gt;
vnoremap &amp;lt; &amp;lt;gv&lt;br /&gt;
vnoremap &amp;gt; &amp;gt;gv&lt;/p&gt;
&lt;p&gt;&quot; Generic highlight changes&lt;br /&gt;
highlight Comment cterm=none ctermfg=Gray&lt;br /&gt;
highlight IncSearch cterm=none ctermfg=Black ctermbg=DarkYellow&lt;br /&gt;
highlight Search cterm=none ctermfg=Black ctermbg=DarkYellow&lt;br /&gt;
highlight String cterm=none ctermfg=DarkGreen&lt;br /&gt;
highlight treeDir cterm=none ctermfg=Cyan&lt;br /&gt;
highlight treeUp cterm=none ctermfg=DarkYellow&lt;br /&gt;
highlight treeCWD cterm=none ctermfg=DarkYellow&lt;br /&gt;
highlight netrwDir cterm=none ctermfg=Cyan&lt;/p&gt;
&lt;p&gt;&quot; Set the &amp;lt;leader&amp;gt; for combo commands&lt;br /&gt;
let mapleader = &quot;,&quot;&lt;/p&gt;
&lt;p&gt;nmap &amp;lt;silent&amp;gt; &amp;lt;c-n&amp;gt; :NERDTreeToggle&amp;lt;cr&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Chunkhost Review: ChunkHost VPS - Hosting Review</title><link>https://chrisk.io/posts/hosting-review-chunkhost-vps/</link><guid isPermaLink="true">https://chrisk.io/posts/hosting-review-chunkhost-vps/</guid><description>I&apos;m not one to typically click on advertisements on social media sites, but when the ad told me I could get a &apos; Free 512MB VPS during beta period &apos;...I…</description><pubDate>Wed, 20 Jul 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m not one to typically click on advertisements on social media sites, but when the ad told me I could get a &apos;&lt;a href=&quot;http://chunkhost.com/r/kungfugrep&quot;&gt;Free 512MB VPS during beta period&lt;/a&gt;&apos;...I instinctively clicked on that link. Let&apos;s fact it, you want to give me a free server for a short time, I&apos;m your guy. I moved a few of my sites over to this new VPS and have been running them (including this site) off the server for the beta period, and now it&apos;s time to pay up. I&apos;ve decided to keep this VPS with &lt;a href=&quot;http://chunkhost.com/r/kungfugrep&quot;&gt;ChunkHost&lt;/a&gt; for a while to see how it runs but I wanted to give you a little heads up on how things have been going with their service.&lt;/p&gt;
&lt;p&gt;**Full Disclosure Notice, the links in this article will credit me with you signing up for a beta and at the completion of your beta, if you complete a survey I receive a small credit for your participation. If you wish to not give me credit for the referral you can simply visit ChunkHost.com**&lt;/p&gt;
&lt;p&gt;I&apos;ve divided the review into 5 areas rated from 1-5 (5 being the best).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Customer Support&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Hardware&lt;/li&gt;
&lt;li&gt;Software&lt;/li&gt;
&lt;li&gt;Account Features&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Customer Support - Rating: 5&lt;/strong&gt;&lt;br /&gt;
About half-way through my Beta Period with ChunkHost, I hadn&apos;t had any issues with my VPS. No downtime, no connectivity issues, etc. Things were working GREAT! I was about to engage in a new project and I was concerned about CPU Cycles. I&apos;ve seen VPS hosts before that would suspend your services had you passed their threshold of &apos;reasonable CPU resources&apos;. This is all fair and well but I was curious at what point I would be responsible for this. I sent off an email to customer support and received the following response within 8 hours:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;No, the virtualization software is really good at mediating fair access to the CPU. Plenty of chunks just sit there burning 100% CPU 24/7. It&apos;s fine!&lt;/p&gt;
&lt;p&gt;The one thing the software isn&apos;t great at is balancing fair IO usage, so hammering the disk is something you shouldn&apos;t do, but that&apos;s generally not a problem!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This may seem like an everyday answer but having worked in the technical support field before, there were two things that impressed me about this answer.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I was given a specific answer to what my limit was...None! I could use up 100% CPU Usage on my VPS without causing any issues with the Virtualization software.&lt;/li&gt;
&lt;li&gt;I was given a specific answer to what WOULD cause an issue with performance, without me asking about it. From my interactions with support, they are staffing it with people who have the same types of questions I do, and are prepared to answer them.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;On top of their support email address, they have a VERY active Twitter account that you can follow @ChunkHost&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Documentation - Rating: 5&lt;/strong&gt;&lt;br /&gt;
When it comes to VPS accounts, us users are mostly on our own. A VPS is like the Condominium of the hosting world. You are sharing the building space, but you need to manage and maintain your section of it. With that in mind, a well setup documentation system is ideal for VPS companies. There are 3 ways you can really get information without asking for it on ChunkHost. You can visit their GetSatisfaction page, check out the F.A.Q. or visit the ChunkHost wiki @ http://wiki.chunkhost.com/. What&apos;s great about this is, you can dig around yourself before asking questions. This wiki includes things like SSH basics for beginners, which is GREAT! This helps those who aren&apos;t 100% comfortable letting go of their GUI get into the CLI managed servers.&lt;/p&gt;
&lt;p&gt;There were two things I found most interesting about the wiki. One was that they offered how-to&apos;s on every day tasks instead of assuming we all knew how to setup an email server. Secondly, they went into detail on how to secure your chunk. This is SUPER important in recent times as security is at the forefront of everyone&apos;s mind.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hardware - Rating: 4&lt;/strong&gt;&lt;br /&gt;
Overall, the stability of the hardware has been very acceptable. I&apos;m running the 512MB Chunk which seems to always carry about 50-100MB of free ram while running a few WordPress sites. Keep in mind this is while running Apache2, PHP, MySQL, and APC all on the same box. I&apos;m given 20GB of storage, which is plenty for a web server, and my system information tools show a total of 16 cores (4 x quad core) at my disposal. My current uptime reads &apos;37 days 4 hours 13 minutes&apos; and the restart was me being paranoid about script I was running taking up too much memory and causing the server to swap.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Software - Rating: 4&lt;/strong&gt;&lt;br /&gt;
While it&apos;s up to me to manage the software installed on the server, the OS choices are from a list provided by &lt;a href=&quot;http://chunkhost.com/r/kungfugrep&quot;&gt;ChunkHost&lt;/a&gt;. They currently include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 8.04(LTS)&lt;/li&gt;
&lt;li&gt;Ubuntu 10.04(LTS)&lt;/li&gt;
&lt;li&gt;Ubuntu 10.10&lt;/li&gt;
&lt;li&gt;Debian 5&lt;/li&gt;
&lt;li&gt;Debian 6&lt;/li&gt;
&lt;li&gt;CentOS 5.4&lt;/li&gt;
&lt;li&gt;CentOS 5.5&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While this is a great list of proven server builds of popular distros, I&apos;d like to see a few other of the big players in the mix. This is a very complete list. One thing I do commend ChunkHost is allowing the LTS versions of Ubuntu to be installed as well as a latest release.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Account Features - Rating: 5&lt;/strong&gt;&lt;br /&gt;
Account settings are one&apos;s held outside of the server itself, and in your &lt;a href=&quot;http://chunkhost.com/r/kungfugrep&quot;&gt;ChunkHost&lt;/a&gt; account. My favorite &apos;feature&apos; by far is how quickly and easily you can have your chunk setup and ready for you to access. A single page asking you for the information for this chunk and you are done. The rest is up to you via the command prompt.&lt;/p&gt;
&lt;p&gt;I also really like the fact that making your Reverse DNS correct is VERY easy. So many times it&apos;s a pain in the arse to get rDNS properly configured with your host, ChunkHost makes it as easy as type and save.&lt;/p&gt;
&lt;p&gt;While your actual account management and billing options are minimal at best...I feel they meet my needs. I don&apos;t need a fancy control panel to schedule a payment or change my card on file. I just need it to work. Simple as that. They also make it easy to setup your referral links so you can get credit for telling your visitors about ChunkHost.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overall - Rating: 4.6&lt;/strong&gt;&lt;br /&gt;
I&apos;ve been in the VPS game for a while and this was a great service that was simple to use, no bells or whistles and was able to quickly expand my web tier. I&apos;ll be continuing my services with ChunkHost until it no longer meets my needs.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://chunkhost.com/r/kungfugrep&quot;&gt;Signup for your FREE Beta of ChunkHost&apos;s 512MB VPS running off their new Xen architecture&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Mapping Command Key to Control in Ubuntu Linux</title><link>https://chrisk.io/posts/mapping-command-key-control-linux/</link><guid isPermaLink="true">https://chrisk.io/posts/mapping-command-key-control-linux/</guid><description>A quick tutorial for setting up a Mac keyboard to work in Linux with the proper key maps.</description><pubDate>Sun, 10 Jul 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve mentioned it before, but I used to be a Mac OS X user for about 10 years. When I switched over to Linux, I did so on my Apple hardware. There are a few things that I just could not get used to when it came to configuration. One of those things was, the &apos;ctrl&apos; key. It was so ingrained in my brain to use &apos;Command+C&apos; to copy, not control+c. Well, Gnome&apos;s configuration settings came to the rescue. You can map the Command key to act as your Control key vary easily.&lt;/p&gt;
&lt;p&gt;First open up your Menu and get to the Control Center. Once open, you are looking for your Keyboard Preferences, of which we want the &apos;Layouts&apos; tab.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/images/blog/layout.png&quot;&gt;&lt;img src=&quot;/images/blog/layout1.png&quot; alt=&quot;&quot; title=&quot;Gnome Keyboard Layout&quot; /&gt;&lt;/a&gt; Go to Control Center-&amp;gt;Keyboard-&amp;gt;Layouts&lt;/p&gt;
&lt;p&gt;Select the &apos;Options&apos; button, and you&apos;ll be presented with a dialog of many items to customize your keyboard layout. Click on the &apos;Alt/Win key behavior&apos; item so it expands. Choose &apos;Control is mapped to Win keys (and the usual Ctrl keys). Close out those two windows and it&apos;s magic! You can now use your Mac Keyboard like it&apos;s a Mac. No more missed copy/paste moments.&lt;/p&gt;
</content:encoded></item><item><title>Connecting to SSH without a Password</title><link>https://chrisk.io/posts/connecting-ssh-password/</link><guid isPermaLink="true">https://chrisk.io/posts/connecting-ssh-password/</guid><description>When dealing with Linux servers, the preferred mode of connection is via SSH. The Secure Shell is one that allows for an encrypted connection between you…</description><pubDate>Sat, 09 Jul 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When dealing with Linux servers, the preferred mode of connection is via SSH. The Secure Shell is one that allows for an encrypted connection between you and the remote server. As often as I connect to these boxes, I am always looking for a way to speed up tasks that I will do more than 3-5 times a day. Typically, an SSH connection will need to have the entry of a password. This is all well and good, however, what if we could create an &apos;Asymmetric Key Pair&apos; and never need a password when on the machine you set this up on? Sounds like a winner to me.&lt;/p&gt;
&lt;p&gt;A little information about a key pair. There are two key generated, a private key (kept local only) and a public key (shared with your server). Creating this pair with the DSA algoryhthem creates a 1024 bit key to secure your connection, which is typically longer than any user generated password for sure.&lt;/p&gt;
&lt;p&gt;Here&apos;s the steps. First off, load up a terminal window and we&apos;re going to create the key pair. To do this we&apos;ll use the ssh-keygen command. You will be asked to enter a file path (I hit enter for default) and a pass-phrase (for an extra layer of security):&lt;/p&gt;
&lt;p&gt;$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/username/.ssh/id_dsa.
Your public key has been saved in /home/username/.ssh/id_dsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx username@HostName
The key&apos;s randomart image is:
.......&lt;/p&gt;
&lt;p&gt;So now we&apos;ve crated your key pair locally, it&apos;s time to tell your server about it. We can do this with one easy line:&lt;/p&gt;
&lt;p&gt;$ ssh-copy-id -i ~/.ssh/id_dsa.pub remote_username@remotehost&lt;/p&gt;
&lt;p&gt;After that you should be able to simply type in a single line to connect to SSH, no password needed.&lt;/p&gt;
&lt;p&gt;$ ssh remote_username@remotehost&lt;/p&gt;
</content:encoded></item><item><title>Using Find and Grep to search your code base</title><link>https://chrisk.io/posts/find-grep-search-code-base/</link><guid isPermaLink="true">https://chrisk.io/posts/find-grep-search-code-base/</guid><description>Let&apos;s face it, when you are in the middle of developing your most recent genius idea, there are times you just need to find every instance of a function…</description><pubDate>Thu, 07 Jul 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Let&apos;s face it, when you are in the middle of developing your most recent genius idea, there are times you just need to find every instance of a function being used. For this, we can revert to the &apos;find&apos; and &apos;grep&apos; commands to narrow things down a bit. First, a little bit about the tools we&apos;ll use:&lt;/p&gt;
&lt;h5&gt;Pipe, |&lt;/h5&gt;
&lt;p&gt;The pipe or | character is used to join command line requests into a single input and output. We&apos;ll be using it to start the find command, look for an occurring, and avoid a negative case...all on the same data set.&lt;/p&gt;
&lt;h5&gt;Find&lt;/h5&gt;
&lt;p&gt;The find command is used to locate files on a Unix or Linux system. find will search any set of directories you specify for files that match the supplied search criteria. You can search for files by name, owner, uhoup, type, permissions, date, and other criteria. The search is recursive in that it will search all subdirectories too. In our case, we&apos;re going to be looking at all files from the current directory and all sub-directories. This is noted by the period character &apos;.&apos;&lt;/p&gt;
&lt;h5&gt;Xargs&lt;/h5&gt;
&lt;p&gt;We will be using the &apos;xargs&apos; command to build and execute command lines from standard input.&lt;/p&gt;
&lt;h5&gt;Grep&lt;/h5&gt;
&lt;p&gt;Grep is used to print lines matching a pattern. In our case we&apos;ll be using the basic usage, as well as the &apos;-v&apos; flag, for inversing the match. In this case, I use it to avoid any occurrences of the search term in a .svn folder.&lt;/p&gt;
&lt;p&gt;So on with the commandline. So, I would like to search for all instances where my current project uses the &apos;foo&apos; function:&lt;/p&gt;
&lt;p&gt;$ find . | xargs grep &quot;foo(&quot; | grep -v .svn&lt;/p&gt;
</content:encoded></item><item><title>Check Linux Version from Command Line</title><link>https://chrisk.io/posts/check-linux-version-command-line/</link><guid isPermaLink="true">https://chrisk.io/posts/check-linux-version-command-line/</guid><description>When you are running a command line only version of Linux, on a server for instance, keeping up to date can fall to the wayside in your daily use as there…</description><pubDate>Wed, 06 Jul 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When you are running a command line only version of Linux, on a server for instance, keeping up to date can fall to the wayside in your daily use as there is no nagging icon to tell you there are updates. One of the most useful directories you can peek around in is the &apos;/proc&apos; directory, just off of root. This directory contains text files that have information ranging form memory stats, swap information, cpu information, cryptographic information, and even...the version of your current Linux Kernel. This can be useful when you are preparing to apply a kernel patch or upgrade to your system.&lt;/p&gt;
&lt;p&gt;To do this we are going to use the &apos;&lt;a href=&quot;https://chrisk.io/tag/cat&quot;&gt;cat&lt;/a&gt;&apos; command in Linux. This is short for conCATenate, meaning to stitch together, however we are going to use the command to simply display some text from a file.&lt;/p&gt;
&lt;p&gt;The following will give you a nice printout of the exact Kernel version you are running on:&lt;/p&gt;
&lt;p&gt;$ cat /proc/version
Linux version 2.6.38-8-generic (buildd@allspice) (gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu3) ) #42-Ubuntu SMP Mon Apr 11 03:31:24 UTC 2011&lt;/p&gt;
&lt;p&gt;This shows what version I am using, which is currently &lt;a href=&quot;http://www.linuxmint.com&quot;&gt;Linux Mint 11&lt;/a&gt; (based on Ubuntu)&lt;/p&gt;
&lt;p&gt;These types of tools can be really useful when combined with applications like &lt;a href=&quot;http://conky.sourceforge.net/&quot;&gt;Conky&lt;/a&gt;, the desktop based system information display.&lt;/p&gt;
&lt;p&gt;A few other useful files you can &apos;cat&apos; are:&lt;/p&gt;
&lt;p&gt;# Memory Information
$ cat /proc/meminfo&lt;/p&gt;
&lt;p&gt;# Version Signature&lt;br /&gt;
$ cat /proc/version_signature&lt;/p&gt;
&lt;p&gt;# Swap Partition Information&lt;br /&gt;
$ cat /proc/swaps&lt;/p&gt;
&lt;p&gt;# CPU Information&lt;br /&gt;
$ cat /proc/cpuinfo&lt;/p&gt;
</content:encoded></item><item><title>Selecting Your Default Linux Shell</title><link>https://chrisk.io/posts/selecting-default-linux-shell/</link><guid isPermaLink="true">https://chrisk.io/posts/selecting-default-linux-shell/</guid><description>When I got my server up and running, it was dumping me into a default C-Shell. I am familiar with the Bourne Again SHell, or BASH . I kept having to invoke…</description><pubDate>Tue, 05 Jul 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I got my server up and running, it was dumping me into a default C-Shell. I am familiar with the &lt;a href=&quot;http://en.wikipedia.org/wiki/Bash_(Unix_shell)&quot;&gt;Bourne Again SHell, or BASH&lt;/a&gt;. I kept having to invoke the BASH shell upon login, which just get&apos;s annoying. Here&apos;s how I defaulted my user to use the BASH shell.&lt;/p&gt;
&lt;p&gt;$ sudo vim /etc/passwd&lt;/p&gt;
&lt;p&gt;This will give you a long listing of user accounts on your Linux OS. The items are a colon &quot;:&quot; sperated value list. Here&apos;s a breakdown of what everything means:&lt;/p&gt;
&lt;p&gt;username:encrypted password field:user id (UID):group id (GID):Real Name:Home Directory:Shell&lt;/p&gt;
&lt;p&gt;So for my user to be defaulted to the BASH shell:&lt;/p&gt;
&lt;p&gt;username:x:1000:1000::/home/username:/bin/bash&lt;/p&gt;
&lt;p&gt;Cheers!&lt;/p&gt;
</content:encoded></item><item><title>sudo su vs. sudo su -</title><link>https://chrisk.io/posts/sudo-su-vs-sudo-su/</link><guid isPermaLink="true">https://chrisk.io/posts/sudo-su-vs-sudo-su/</guid><description>I&apos;ve always wondered this but finally got the answer as to why you should use: $ sudo su - instead of using: $ sudo su When adding the &apos;-&apos; character to the…</description><pubDate>Wed, 29 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve always wondered this but finally got the answer as to why you should use:&lt;br /&gt;
&lt;code&gt;$ sudo su -&lt;/code&gt;&lt;br /&gt;
instead of using:&lt;br /&gt;
&lt;code&gt;$ sudo su&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;When adding the &apos;-&apos; character to the end of this command, you are also put into the PATH of the superuser. Without it, you cannot access things like the &apos;service&apos; command for restarting services.&lt;/p&gt;
</content:encoded></item><item><title>Ubuntu sendmail delays with PHP mail()</title><link>https://chrisk.io/posts/ubuntu-sendmail-delays-php-mail/</link><guid isPermaLink="true">https://chrisk.io/posts/ubuntu-sendmail-delays-php-mail/</guid><description>I was working on a project recently and was trying to send an email via my PHP script using the mail() command when it would appear that my site would just…</description><pubDate>Mon, 27 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I was working on a project recently and was trying to send an email via my PHP script using the mail() command when it would appear that my site would just sit and wait for the email to be sent, taking sometimes a minute or two for the page to load. The email would successfully send, however it took forever for my pages to load while trying to send.&lt;/p&gt;
&lt;p&gt;To fix this issue, we can do two quick things and you&apos;ll be off and sending email.&lt;/p&gt;
&lt;p&gt;First, get your hostname:&lt;/p&gt;
&lt;p&gt;$ hostname
your-host-name&lt;/p&gt;
&lt;p&gt;Your hostname will be printed out and then we need to edit your /ect/hosts file, which is used for DNS resolution by your system. Open up the file with your favorite editor:&lt;/p&gt;
&lt;p&gt;$ sudo vim /etc/hosts&lt;/p&gt;
&lt;p&gt;You may see a line that looks like the following:&lt;/p&gt;
&lt;p&gt;127.0.0.1     localhost&lt;/p&gt;
&lt;p&gt;We want it to read:&lt;/p&gt;
&lt;p&gt;127.0.0.1    localhost localhost.localdomain your-host-name&lt;/p&gt;
&lt;p&gt;Obviously replace your-host-name with what the hostname command outputs.&lt;/p&gt;
&lt;p&gt;Post Image via Flickr and CC by &lt;a href=&quot;http://www.flickr.com/photos/pacdog/4968422200/&quot;&gt;Pacdog&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Find Disk Usage by Folder with du</title><link>https://chrisk.io/posts/find-disk-usage-folder-du/</link><guid isPermaLink="true">https://chrisk.io/posts/find-disk-usage-folder-du/</guid><description>Something I&apos;m always curious about is where my disk space always goes. Honestly, it&apos;s amazing how quickly you can fill up a hard drive these days. Linux has…</description><pubDate>Wed, 15 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Something I&apos;m always curious about is where my disk space always goes. Honestly, it&apos;s amazing how quickly you can fill up a hard drive these days. Linux has a great tool called &apos;du&apos; (disk usage) that we can leverage to see where all our GB are escaping to.&lt;/p&gt;
&lt;p&gt;There&apos;s a few flags you&apos;ll want to use before you just go and start using &apos;du&apos; only.&lt;/p&gt;
&lt;p&gt;Navigate to the directory you would like to check up on, in this case, my web server root:&lt;/p&gt;
&lt;p&gt;$ cd /var/www/
$ du --max-depth=1 -h
58M	./www.chriskdesigns.com
32M	./stock_wordpress
17M	./www.binbash.in
106M	.&lt;/p&gt;
&lt;p&gt;So I&apos;m using 106MB of disk space with websites currently. This can be extremely useful with large media sites.&lt;/p&gt;
&lt;p&gt;Let&apos;s look at those flags:&lt;/p&gt;
&lt;p&gt;--max-depth=1 - Tells us to only look at the current directory and the folders in it, not recursively
-h - &apos;Human Readable&apos;, so you&apos;ll get things like 10M or 54G&lt;/p&gt;
&lt;p&gt;For all the flags hit up the man pages with:&lt;/p&gt;
&lt;p&gt;$ du man&lt;/p&gt;
</content:encoded></item><item><title>Create Random Passwords with makepasswd</title><link>https://chrisk.io/posts/creating-randomly-generated-passwords/</link><guid isPermaLink="true">https://chrisk.io/posts/creating-randomly-generated-passwords/</guid><description>We all know the best way to have a secure password is for it to be random. There are a ton of sites out there that will give you a password, but your Linux…</description><pubDate>Tue, 14 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We all know the best way to have a secure password is for it to be random. There are a ton of sites out there that will give you a password, but your Linux command line can do it for you with one command. You may need to install it with your favorite package manager:&lt;/p&gt;
&lt;p&gt;$ sudo apt-get install makepasswd&lt;/p&gt;
&lt;p&gt;$ makepasswd&lt;br /&gt;
JAvMdvMu&lt;/p&gt;
&lt;p&gt;Here&apos;s a readout of the man page:&lt;/p&gt;
&lt;p&gt;makepasswd v1.10, a utility to generate and/or encrypt passwords.&lt;/p&gt;
&lt;p&gt;Copyright (c) 1997-1999 by Rob Levin &lt;a href=&quot;mailto:levin@openproject.net&quot;&gt;levin@openproject.net&lt;/a&gt;.  All rights are reserved by&lt;br /&gt;
the author.  This program may be used under the terms of version 2 of the&lt;br /&gt;
GNU Public License.&lt;/p&gt;
&lt;p&gt;Last modified on Monday, 7 April 1999 at 22:56 (UCT).&lt;/p&gt;
&lt;p&gt;Format:          makepasswd [option...]&lt;/p&gt;
&lt;p&gt;Options are:&lt;/p&gt;
&lt;p&gt;--chars=N        Generate passwords with exactly N characters (do not use with&lt;br /&gt;
options --minchars and --maxchars).&lt;br /&gt;
--clearfrom=FILE Use a clear password from FILE instead of generating passwords.&lt;br /&gt;
Requires the --crypt or --crypt-md5 option; may not be&lt;br /&gt;
used with options --chars, --maxchars, --minchars,&lt;br /&gt;
--count, --string, --nocrypt.  Trailing newlines are&lt;br /&gt;
ignored, other whitespace is not.&lt;br /&gt;
--count=N        Produce a total of N passwords (the default is one).&lt;br /&gt;
--crypt          Produce encrypted passwords.&lt;br /&gt;
--crypt-md5      Produce encrypted passwords using the MD5 digest (hash)&lt;br /&gt;
algorithm.&lt;br /&gt;
--cryptsalt=N    Use crypt() salt N, a positive number &amp;lt;= 4096.  If random&lt;br /&gt;
seeds are desired, specify a zero value (the default).&lt;br /&gt;
--help           Ignore other operands and produce only this help display.&lt;br /&gt;
--maxchars=N     Generate passwords with at most N characters (default=10).&lt;br /&gt;
--minchars=N     Generate passwords with at least N characters (default=8).&lt;br /&gt;
--nocrypt        Do not encrypt the generated password(s) (the default).&lt;br /&gt;
--noverbose      Display no labels on output (the default).&lt;br /&gt;
--randomseed=N   Use random number seed N, between 0 and 2^32 inclusive.  A zero&lt;br /&gt;
value results in a real-random seed.  This option&lt;br /&gt;
generates predictable passwords, and should normally&lt;br /&gt;
be avoided.&lt;br /&gt;
--rerandom=N     Set the random seed value every N values used.  Specify zero&lt;br /&gt;
to use a single seed value (the default).  Specify&lt;br /&gt;
one to get true-random passwords, but plan on hitting&lt;br /&gt;
the CONTROL key a lot while it&apos;s running. ;)&lt;br /&gt;
--repeatpass=N   Use each password N times (4096 maximum, --crypt or&lt;br /&gt;
--crypt-md5 must be set and --cryptsalt may not be set).&lt;br /&gt;
--string=STRING  Use the characters in STRING to generate random passwords.&lt;br /&gt;
--verbose        Display labelling information on output.&lt;/p&gt;
</content:encoded></item><item><title>Adobe AIR unable to access ELS</title><link>https://chrisk.io/posts/adobe-air-unable-to-access-els/</link><guid isPermaLink="true">https://chrisk.io/posts/adobe-air-unable-to-access-els/</guid><description>Adobe AIR keeps the passwords and account information of your AIR application in what they call the Encrypted Local Storage or ELS. Well on Linux, this can…</description><pubDate>Tue, 12 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Adobe AIR keeps the passwords and account information of your AIR application in what they call the Encrypted Local Storage or ELS. Well on Linux, this can sometimes get confused, corrupted, or just wonky if your Gnome Keyring is out of sync or has an issue. Luckely I was given the link to &lt;a href=&quot;http://kb2.adobe.com/cps/492/cpsid_49267.html&quot;&gt;Troubleshooting AIR&apos;s Encrypted Local Storage (ELS) on Linux&lt;/a&gt; from the AIR application screaming at me about this. I ran the check to see if the Daemon was running:&lt;/p&gt;
&lt;p&gt;$ ps -aef | grep -i &apos;gnome.*keyring&apos;
1000      3923     1  0 00:39 ?        00:00:00 /usr/bin/gnome-keyring-daemon --daemonize --login
1000      8884  8869  0 09:05 pts/0    00:00:00 grep --colour=auto -i gnome.*keyring&lt;/p&gt;
&lt;p&gt;Well, we can see that it is running, so skip on to step 3 of that guide and we&apos;ll see:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As ELS is not accessible, all previously stored data in ELS cannot be retrieved anymore. To start using ELS again, we need to reset ELS, by deleting the following directory&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So let&apos;s give this a shot:&lt;/p&gt;
&lt;p&gt;$ rm -rf ~/.appdata/Adobe/AIR/ELS&lt;/p&gt;
&lt;p&gt;Sure enough, all my data was cleared from the ELS, but my AIR applications could start once again. WOOT!&lt;/p&gt;
</content:encoded></item><item><title>Nvidia Display tool incorrectly wrote xorg.conf</title><link>https://chrisk.io/posts/nvidia-display-tool-incorrectly-wrote-xorg-conf/</link><guid isPermaLink="true">https://chrisk.io/posts/nvidia-display-tool-incorrectly-wrote-xorg-conf/</guid><description>My xorg.conf file was improperly written by the nVidia xserver configuration tool today, and wouldn&apos;t you know it, it was when I had just gotten to the…</description><pubDate>Fri, 08 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;My xorg.conf file was improperly written by the nVidia xserver configuration tool today, and wouldn&apos;t you know it, it was when I had just gotten to the Airport and didnt&apos; have wifi yet. It&apos;s cool. just a little reading of the error logs showed me I needed to do 1 quick thing.&lt;/p&gt;
&lt;p&gt;My &apos;ServerLayout&apos; section looked like this:&lt;/p&gt;
&lt;p&gt;Section &quot;ServerLayout&quot;
Identifier     &quot;Layout0&quot;
Screen     0   &quot;Screen0&quot; -1600-0
InputDevice    &quot;Keyboard0&quot; &quot;CoreKeyboard&quot;
InputDevice    &quot;Mouse0&quot; &quot;CorePointer&quot;
Option         &quot;Xinerama&quot; &quot;0&quot;
EndSection&lt;/p&gt;
&lt;p&gt;This was for my dual monitor hookup that I have at home. Well guess what isn&apos;t there....my 2nd monitor and the tool I used to re-write the conf file did so incorrectly. It should look like this:&lt;/p&gt;
&lt;p&gt;Section &quot;ServerLayout&quot;
Identifier     &quot;Layout0&quot;
Screen         &quot;Screen0&quot;
InputDevice    &quot;Keyboard0&quot; &quot;CoreKeyboard&quot;
InputDevice    &quot;Mouse0&quot; &quot;CorePointer&quot;
Option         &quot;Xinerama&quot; &quot;0&quot;
EndSection&lt;/p&gt;
</content:encoded></item><item><title>Using .bashrc aliases to save time</title><link>https://chrisk.io/posts/using-bashrc-aliases-to-save-time/</link><guid isPermaLink="true">https://chrisk.io/posts/using-bashrc-aliases-to-save-time/</guid><description>As a developer there are actions I do over and over that can be quite repetitive in the CLI. Some of these commands require specific flags to be set or a…</description><pubDate>Thu, 07 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As a developer there are actions I do over and over that can be quite repetitive in the CLI. Some of these commands require specific flags to be set or a long string of sources and destinations. I&apos;ve found it easier to write aliases into my .bashrc file in order to mediate that.&lt;/p&gt;
&lt;p&gt;The .bashrc file is in your home directory (~/ or /home/username/) and is an invisible file (starting with a &apos;.&apos;) that contains aliases and environmental variables for your bash session.&lt;/p&gt;
&lt;p&gt;First, let&apos;s open your .bashrc file:&lt;br /&gt;
&lt;code&gt;$ vim ~/.bashrc&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Once open, enter the following after the last entry.&lt;/p&gt;
&lt;p&gt;# User specific aliases and functions
alias ..=&quot;cd ..&quot;&lt;/p&gt;
&lt;p&gt;Save and exit your bash session and restart terminal (or your bash session if you are running CLI only).&lt;/p&gt;
&lt;p&gt;This entry allows you to simply type &apos;..&apos; instead of &apos;cd ..&apos; to backup one directory.&lt;/p&gt;
&lt;p&gt;Some of the more common aliases I use are:&lt;/p&gt;
&lt;p&gt;#connect to a DB only needing to enter the password
alias sitenamedb=&quot;mysql -u username -p -h hostname databasename&quot;&lt;/p&gt;
&lt;p&gt;#navigate up two directories&lt;br /&gt;
alias ...=&quot;cd ../..&quot;&lt;/p&gt;
&lt;p&gt;#navigate up three directories&lt;br /&gt;
alias ....=&quot;cd ../../..&quot;&lt;/p&gt;
&lt;p&gt;#navigate directly to my downloads folder&lt;br /&gt;
alias downloads=&quot;cd /home/username/downloads&quot;&lt;/p&gt;
</content:encoded></item><item><title>Patching 32-bit .deb for 64-bit</title><link>https://chrisk.io/posts/patching-32-bit-deb-for-64-bit/</link><guid isPermaLink="true">https://chrisk.io/posts/patching-32-bit-deb-for-64-bit/</guid><description>I&apos;ve been finding lots of .deb packages that are compiled for 32-bit OS&apos;s that don&apos;t have 64-bit versions available. While this may not be the most elegant…</description><pubDate>Mon, 04 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been finding lots of .deb packages that are compiled for 32-bit OS&apos;s that don&apos;t have 64-bit versions available. While this may not be the most elegant solution, it&apos;s been allowing me to install things like Adobe AIR and DiffMerge, which don&apos;t have 64-bit .deb packages:&lt;/p&gt;
&lt;p&gt;First, navigate to the location of the .deb folder.&lt;/p&gt;
&lt;p&gt;Once there do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Make a tmp directory to hold the package&lt;br /&gt;
&lt;code&gt;$ mkdir tmp&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extract the .deb package into the tmp directory&lt;br /&gt;
&lt;code&gt;$ dpkg-deb -x package.deb tmp&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extract the control files&lt;br /&gt;
&lt;code&gt;$ dpkg-deb --control package.deb tmp/DEBIAN&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change the Architecture parameter from “i386″ to “all”&lt;br /&gt;
&lt;code&gt;$ sed -i &quot;s/i386/all/&quot; tmp/DEBIAN/control&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Repackage the .deb into your new 64-bit version&lt;br /&gt;
&lt;code&gt;$ dpkg -b tmp package_64.deb&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install the new 64-bit .deb version :)&lt;br /&gt;
&lt;code&gt;$ sudo dpkg -i package_64.deb&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&apos;m not going to say this will work for EVERY package b/c you are essentially faking out the installer to think your system is supported. You may run into some application errors due to this, however, I have experienced none as of yet.&lt;/p&gt;
&lt;p&gt;Adapted from &lt;a href=&quot;http://www.jamesward.com/2010/10/14/install-adobe-air-on-64-bit-ubuntu-10-10/&quot;&gt;jamesward.com&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Find and move all of one type of file</title><link>https://chrisk.io/posts/find-and-move-all-of-one-type-of-file/</link><guid isPermaLink="true">https://chrisk.io/posts/find-and-move-all-of-one-type-of-file/</guid><description>I was doing a little organizing of my home directory and needed a quick way to move all of my .pdf files into my Documents/PDF folder. It&apos;s where I keep all…</description><pubDate>Sat, 02 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I was doing a little organizing of my home directory and needed a quick way to move all of my .pdf files into my Documents/PDF folder. It&apos;s where I keep all PDFs for easy organization. Receipts, financial documents, e-books, etc. Here&apos;s a quick way to find ALL of a file type (recursively of course) and move (or copy if you prefer) to another directory.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;   $ find /home/username/ -iname &quot;*.pdf*&quot; -exec mv {} /home/cklosowski/Documents/pdfs/ ;   &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Again you could also cp instead of mv if you prefer (would end up with duplicates however) by changing it to read:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;   $ find /home/username/ -iname &quot;*.pdf*&quot; -exec cp {} /home/cklosowski/Documents/pdfs/ ;   &lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>Quickly emptying a file</title><link>https://chrisk.io/posts/quickly-emptying-a-file/</link><guid isPermaLink="true">https://chrisk.io/posts/quickly-emptying-a-file/</guid><description>So I was messing around with getting a few logging systems setup for a web app I&apos;m writing and after a while these log files started to grow in size to the…</description><pubDate>Fri, 01 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So I was messing around with getting a few logging systems setup for a web app I&apos;m writing and after a while these log files started to grow in size to the point that it was difficult to find the relevant data quickly. I needed a quick way to empty a file without deleting it. Here&apos;s the trick I learned:&lt;/p&gt;
&lt;p&gt;// First let&apos;s put some text into a file
$ echo &quot;test&quot; &amp;gt; filename.log&lt;/p&gt;
&lt;p&gt;// Let&apos;s display it&lt;br /&gt;
$ cat filename.log&lt;/p&gt;
&lt;p&gt;// and empty it&lt;br /&gt;
$ cat /dev/null &amp;gt; filename.log&lt;/p&gt;
&lt;p&gt;Basically &apos;cat&apos; reads the file contents of whatever you specify, in this case /dev/null which is empty. It then uses the &apos;&amp;gt;&apos; character to push the contents of /dev/null (empty) to filename.log, overwriting anything that currently exists in it.&lt;/p&gt;
</content:encoded></item></channel></rss>