<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[KamilGrzegorczyk.com]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://kamilgrzegorczyk.com/</link><image><url>https://kamilgrzegorczyk.com/favicon.png</url><title>KamilGrzegorczyk.com</title><link>https://kamilgrzegorczyk.com/</link></image><generator>Ghost 5.75</generator><lastBuildDate>Thu, 06 Aug 2026 20:49:24 GMT</lastBuildDate><atom:link href="https://kamilgrzegorczyk.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[WordPress - how to disable plugins on certain environment]]></title><description><![CDATA[Ever wondered how to disable WordPress plugins based on your environment? If yes - read this article.]]></description><link>https://kamilgrzegorczyk.com/2018/05/02/how-to-disable-plugins-on-certain-environment/</link><guid isPermaLink="false">5ae9bfe3fd50c81cdd3ae24e</guid><category><![CDATA[wordpress]]></category><category><![CDATA[development]]></category><category><![CDATA[best practice]]></category><dc:creator><![CDATA[Kamil Grzegorczyk]]></dc:creator><pubDate>Wed, 02 May 2018 16:28:29 GMT</pubDate><media:content url="https://kamilgrzegorczyk.com/content/images/2018/05/pexels-photo-463684.jpeg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://kamilgrzegorczyk.com/content/images/2018/05/pexels-photo-463684.jpeg" alt="WordPress - how to disable plugins on certain environment"><p>Tired of your caching plugin which ruins your experience while developing your next plugin or theme? If you want to learn how to disable WordPress plugins based on the current server environment continue below!</p>
<p>5 years have passed since I initially wrote <a href="https://lowgravity.pl/blog/quick-tip-how-to-disable-wp-plugin-on-certain-page/?ref=kamilgrzegorczyk.com">the tip regarding disabling the WordPress plugin on certain page</a>. Time passed by and this is still a valid method but it&apos;s not enough anymore, we would like to have even more control over our plugins.</p>
<p>Nowadays each of our projects uses plenty of environments. Let&apos;s forget complex setups for a minute (local-&gt;dev-&gt;stage/qa/test-&gt;prod or whatever floats your boat). Almost all of us have at least two environments - local and production.</p>
<p>What if your fancy cache plugin is driving you nuts when you try to develop that next template? You disable it but then it puts <code>define( &apos;WP_CACHE&apos;, false )</code> everywhere and now you are afraid to commit it along with your &quot;real&quot; changes.</p>
<p>What if your analytics or backup plugin should not run on certain environment?</p>
<p>We need a way to be able to tell the plugins &quot;go away&quot; in certain situations and unfortunately WordPress doesn&apos;t have any solution out of the box (and this is actually a good thing, less code =&gt; better product).</p>
<h2 id="thesolution">The solution</h2>
<p>As mentioned in my previous posts I am a big fan of <a href="https://github.com/roots/bedrock?ref=kamilgrzegorczyk.com">Roots/Bedrock</a> architecture so I will propose two solutions. First one is for the guys who still do WP development in old fashion way and second one for all of us, fancy <a href="https://getcomposer.org/?ref=kamilgrzegorczyk.com">Composer</a> kids.</p>
<h4 id="stage1defineyourneeds">Stage 1 - define your needs.</h4>
<p>First of all we have to define the plugins we would like to disable. Let&apos;s use an array stored in constant for that purpose.</p>
<p>In my case I would like to disable Autoptimize (file minification) and Wp Super Cache (page caching) on my local environment.</p>
<pre><code class="language-php">define(&apos;DEV_DISABLED_PLUGINS&apos;, serialize([
	&apos;autoptimize/autoptimize.php&apos;,
	&apos;wp-super-cache/wp-cache.php&apos;
]));
</code></pre>
<p><em>Disclaimer: I know that in PHP7 you can store arrays in a constant without serialization but many WP folks are still on PHP 5.x.</em></p>
<h4 id="stage2aeditingwpconfigphp">Stage 2A - editing wp-config.php</h4>
<p>If you have a regular WordPress architecture:</p>
<p>1.Edit your <code>wp-config.php</code> file (or <code>local-config.php</code>, if you follow that pattern).<br>
2.Paste the <code>define</code> snippet from above. The best way would be to do it over the line saying: <code>/* That&apos;s all, stop editing! Happy blogging. */</code>.<br>
3.Be sure to not push that file to production as in its bare form it wont protect you from disabling these plugins on prod.</p>
<h4 id="stage2beditingapplicationconfigurationofrootsbedrock">Stage 2B - editing application configuration of Roots/Bedrock</h4>
<p>If you use roots/bedrock:</p>
<p>1.Navigate to <code>config/environments</code> directory.<br>
2.Choose the environment you want to apply your changes to. (It can be for example <code>development.php</code>)<br>
3.Paste the define snippet at the end of the file.</p>
<h4 id="stage3definemuplugin">Stage 3 - define MU-Plugin</h4>
<p>Now we need to actually do the disabling part.</p>
<p>There are few ways to do it but the most common one is to leverage <code>option_active_plugins</code> filter. This method is still valid even though it was used first time many years ago.</p>
<p><strong>Let&apos;s define our mu-plugin first</strong><br>
<a href="https://codex.wordpress.org/Must_Use_Plugins?ref=kamilgrzegorczyk.com">You can read what are the mu-plugins here</a>. If you do not use them today think about incorporating them into your codebase.</p>
<p>Go to the:<br>
A) <code>wp-content/mu-plugins</code> (regular WP)<br>
or to<br>
B)<code>web/app/mu-plugins</code> (Roots/Bedrock)<br>
and create a file <code>my-plugin-disabler.php</code> there.</p>
<p><strong>Contents of my-plugin-disabler.php</strong></p>
<pre><code class="language-php">&lt;?php
/*
Plugin Name: Simple Environment plugin disabler
Description:  Disables plugins based on environment settings.
Author: Kamil Grzegorczyk
Version: 0.1
*/
    
if ( defined( &apos;DEV_DISABLED_PLUGINS&apos; ) ) {
    $plugins_to_disable = unserialize( DEV_DISABLED_PLUGINS );
    
    if ( ! empty( $plugins_to_disable ) &amp;&amp; is_array( $plugins_to_disable ) ) {

        require_once( dirname( __FILE__ ) . &apos;/vendor/DisablePlugins.php&apos; );
        $utility = new DisablePlugins( $plugins_to_disable );
        
        //part below is optional but for me it is crucial
        error_log( &apos;Locally disabled plugins: &apos; . var_export( $plugins_to_disable, true ) );
	}
}
</code></pre>
<p>So far so good right? We created mu-plugin and checked if we have defined any plugins to be disabled.</p>
<p>Inside the IF statement we use the magical utility called <code>DisablePlugins</code> but we did not define that anywhere so let&apos;s fix that.</p>
<p><strong>Add DisablePlugins utility</strong><br>
Years ago Mark Jaquith, one of WP Core developers, wrote a small utility to disable plugins using <code>option_active_plugins</code> filter.</p>
<p>Even though it was created like 7 years ago it will be more than enough in our scenario. And we want to be a smart developer who does not need to reinvent the wheel, right?</p>
<p>While still being in the <code>mu-plugins</code> directory please create <code>vendor</code> directory there and paste the following contents to <code>DisablePlugins.php</code> file:</p>
<pre><code class="language-php">&lt;?php
	/**
	 * Plugin disabling engine class
	 * Author: Mark Jaquith
	 * Author URI: http://markjaquith.com/
	 * Plugin URI: https://gist.github.com/markjaquith/1044546
	 * Using fork: https://gist.github.com/Rarst/4402927
	 */

	class DisablePlugins {
		static $instance;
		private $disabled = [];

		/**
		 * Sets up the options filter, and optionally handles an array of plugins to disable
		 * @param array $disables Optional array of plugin filenames to disable
		 */
		public function __construct( Array $disables = NULL ) {
			/**
			 * Handle what was passed in
			 */
			if ( is_array( $disables ) ) {
				foreach ( $disables as $disable ) {
					$this-&gt;disable( $disable );
				}
			}

			/**
			 * Add the filters
			 */
			add_filter( &apos;option_active_plugins&apos;, [ $this, &apos;do_disabling&apos; ] );
			add_filter( &apos;site_option_active_sitewide_plugins&apos;, [ $this, &apos;do_network_disabling&apos; ] );

			/**
			 * Allow other plugins to access this instance
			 */
			self::$instance = $this;
		}

		/**
		 * Adds a filename to the list of plugins to disable
		 */
		public function disable( $file ) {
			$this-&gt;disabled[] = $file;
		}

		/**
		 * Hooks in to the option_active_plugins filter and does the disabling
		 * @param array $plugins WP-provided list of plugin filenames
		 * @return array The filtered array of plugin filenames
		 */
		public function do_disabling( $plugins ) {
			if ( count( $this-&gt;disabled ) ) {
				foreach ( (array)$this-&gt;disabled as $plugin ) {
					$key = array_search( $plugin, $plugins );
					if ( false !== $key ) {
						unset( $plugins[ $key ] );
					}
				}
			}

			return $plugins;
		}

		/**
		 * Hooks in to the site_option_active_sitewide_plugins filter and does the disabling
		 *
		 * @param array $plugins
		 *
		 * @return array
		 */
		public function do_network_disabling( $plugins ) {

			if ( count( $this-&gt;disabled ) ) {
				foreach ( (array)$this-&gt;disabled as $plugin ) {

					if ( isset( $plugins[ $plugin ] ) ) {
						unset( $plugins[ $plugin ] );
					}
				}
			}

			return $plugins;
		}
	}
</code></pre>
<h4 id="conclusion">Conclusion</h4>
<p>It wasn&apos;t so scary was it?</p>
<p>Now you can use that solution on any environment you wish, you can even place it into your production config file if that fits your scenario.</p>
<p>Obviously only in situation where you do not share configs across the environments (another advantage of Roots/Bedrock set up which has separate configs out of the box). If you have one file though you can always rely on IF statements and <code>request_uri</code> detection but this is whole another story.</p>
<p>Take care!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Best practices - naming convention for WordPress custom fields]]></title><description><![CDATA[You do not know how to name your custom fields? Are you noticing weird issues with your data? The solution might be easier than you think.]]></description><link>https://kamilgrzegorczyk.com/2017/10/12/best-practices-naming-convention-for-wordpress-custom-fields/</link><guid isPermaLink="false">59dcda6206281d115734f08f</guid><category><![CDATA[wordpress]]></category><category><![CDATA[development]]></category><category><![CDATA[custom fields]]></category><category><![CDATA[best practice]]></category><category><![CDATA[Advanced Custom Fields]]></category><category><![CDATA[Pods Framework]]></category><dc:creator><![CDATA[Kamil Grzegorczyk]]></dc:creator><pubDate>Thu, 12 Oct 2017 13:42:14 GMT</pubDate><media:content url="https://kamilgrzegorczyk.com/content/images/2017/10/ufo-1379888_960_720.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://kamilgrzegorczyk.com/content/images/2017/10/ufo-1379888_960_720.jpg" alt="Best practices - naming convention for WordPress custom fields"><p>Do you want to learn how to name your WordPress Custom fields properly? What are the risks of not namespacing key names? And why should you care?</p>
<p>Recently I wrote tutorial about filtering WordPress admin views. In the code I named custom fields key like kg_order_items. You could ask why? Why not to name it just items? Well&#x2026; read below!</p>
<p>If you try to google for naming custom fields there is not so much information about it. Even the <a href="https://codex.wordpress.org/Custom_Fields?ref=kamilgrzegorczyk.com">Codex entry</a> tells nothing about naming the field keys properly. I found only <a href="https://support.advancedcustomfields.com/forums/topic/best-practice-for-name-the-fields/?ref=kamilgrzegorczyk.com">one resource at ACF forums</a> which contains proper information.</p>
<p>If there is no problem, what is the fuss about? You could ask.</p>
<p><img src="https://kamilgrzegorczyk.com/content/images/2017/10/dt_c110423.gif" alt="Best practices - naming convention for WordPress custom fields" loading="lazy"></p>
<p>The days when WordPress was a CMS supporting small blog websites with only posts and pages are gone. Today even the smallest website uses plethora of plugins and complex themes. And all of them bring new custom fields into the game.</p>
<p>The situation gets even worse if you use any of the fancy &#x201C;premium&#x201D; themes. Unfortunately many of these are not well written and combine 1001 functions in one. Final result? Slow, not performant, tangled site which looks nice only on demo content and stock images. And they add <mark>a lot</mark> of custom fields too.</p>
<h3 id="danger">Danger!</h3>
<p><img src="https://kamilgrzegorczyk.com/content/images/2017/10/trap.jpg" alt="Best practices - naming convention for WordPress custom fields" loading="lazy"></p>
<p>WordPress <code>wp_postmeta</code> table is very simple. It is a <mark>key=&gt;value</mark> pair attached to particular <mark>post_id</mark>. It means that <mark>all custom fields keys share common namespace</mark>. That is especially true for particular ID of the post.</p>
<p><strong>First example</strong><br>
a) Imagine that your post have a &#x201C;learn more&#x201D; link. After you click the link it redirects you to a particular URL. The address is provided in a custom field. Let&#x2019;s name the field key as <code>redirect_to</code>.</p>
<p>b) Now imagine that you install a plugin called for example &#x201C;Redirect me Honey&#x201D;. The plugin is very, very simple. When user enters the page it immediately redirects the users based on custom field setting attached to a post. Oh&#x2026; and its field key is named <code>redirect_to</code> as well..</p>
<p>Result? After you activate the plugin all of your posts with &#x201C;learn more&#x201D; button are redirecting users out of your website. And the reason why is not obvious at the first sight. It may even be unnoticed for quite a while.</p>
<p>This scenario is of course made up but the dangers are real. With thousands of plugins and thousands of themes available it&apos;s just a matter of time to encounter such name collision.</p>
<p><strong>Second example</strong><br>
WordPress can store multiple values for the same key name and post ID. (Unless you provide special parameter called <code>$unique</code>).</p>
<p>It means that if you save your data 5 times under the key location you will receive an array consisting of 5 elements when calling get_post_meta().</p>
<p>Let&#x2019;s assume that you have a post about the cities you have visited. You have been to 5 cities and those locations are shown on the embedded map in the post. Simple, right?</p>
<p>Attention! Not useful code ahead&#xA0;;)&#xA0;!</p>
<pre><code class="language-php">add_post_meta($post_id, &apos;location&apos;, &apos;40.7127753, 73.989308&apos;); //NY
add_post_meta($post_id, &apos;location&apos;, &apos;34.0522342, -118.2436849&apos;); //LA
add_post_meta($post_id, &apos;location&apos;, &apos;48.856614, 2.3522219000000177&apos;); //Paris
add_post_meta($post_id, &apos;location&apos;, &apos;48.2081743,16.37381890000006&apos;); //Vienna
add_post_meta($post_id, &apos;location&apos;, &apos;41.90278349999999,12.496365500000024&apos;); //Rome

var_dump(get_post_meta($post_id, &apos;location&apos;);
array (size=5)
  0 =&gt; string &apos;40.7127753, 73.989308&apos; (length=21)
  1 =&gt; string &apos;34.0522342, -118.2436849&apos; (length=24)
  2 =&gt; string &apos;48.856614, 2.3522219000000177&apos; (length=29)
  3 =&gt; string &apos;48.2081743,16.37381890000006&apos; (length=28)
  4 =&gt; string &apos;41.90278349999999,12.496365500000024&apos; (length=36)
</code></pre>
<p>What if after a while you use a theme or plugin which can set the position of a post on a front page. You can pick between slider, sidebar or featured posts etc. This scenario may end up like this:</p>
<pre><code class="language-php">array (size=6)
  0 =&gt; string &apos;40.7127753, 73.989308&apos; (length=21)
  1 =&gt; string &apos;34.0522342, -118.2436849&apos; (length=24)
  2 =&gt; string &apos;48.856614, 2.3522219000000177&apos; (length=29)
  3 =&gt; string &apos;48.2081743,16.37381890000006&apos; (length=28)
  4 =&gt; string &apos;41.90278349999999,12.496365500000024&apos; (length=36)
  5 =&gt; string &apos;left_sidebar&apos; (length=12) // Yeah, right...
</code></pre>
<p>Or worse</p>
<pre><code class="language-php">array (size=5)
  0 =&gt; string &apos;left_sidebar&apos; (length=12)
  1 =&gt; string &apos;left_sidebar&apos; (length=12)
  2 =&gt; string &apos;left_sidebar&apos; (length=12)
  3 =&gt; string &apos;left_sidebar&apos; (length=12)
  4 =&gt; string &apos;left_sidebar&apos; (length=12)
</code></pre>
<p>Your pretty little map is broken now! And you lost all of your entered data. Not funny right?</p>
<p><img src="https://kamilgrzegorczyk.com/content/images/2017/10/danbo-1873167_1280.jpg" alt="Best practices - naming convention for WordPress custom fields" loading="lazy"><br>
B-b-b-b-broken?</p>
<h3 id="solution">Solution</h3>
<p>You can never protect your custom fields data from being overwritten or deleted. This is how WordPress works and why it is so flexible. You can reduce that risk though.</p>
<p><strong>How?</strong><br>
By avoiding common names and namespacing all your custom fields keys.<br>
My proposed convention is:</p>
<ul>
<li>cpt-name_field-name<br>
e.g. &#x201C;books_author&#x201D; instead of &#x201C;author&#x201D;, &#x201C;order_items&#x201D; instead of &#x201C;items&#x201D; (solution for most lazy ones&#xA0;:) ).</li>
<li>purpose_field-name<br>
e.g. &#x201C;front_page_location&#x201D; instead of &#x201C;location&#x201D;, &#x201C;visited_cities_locations&#x201D; instead of &#x201C;location&#x201D;.</li>
<li>prefix_(cpt-name/purpose)_field-name<br>
e.g. &#x201C;kg_map_location&#x201D;, &#x201C;kg_visited_cities_locations&#x201D; (for the most strict ones).</li>
</ul>
<p>That is not all. Additionally you should always take care of optional parameters of built-in WordPress functions:</p>
<ul>
<li><a href="https://codex.wordpress.org/Function_Reference/add_post_meta?ref=kamilgrzegorczyk.com">add_post_meta()</a> has $unique to not add the custom field if it already exists.</li>
<li><a href="https://codex.wordpress.org/Function_Reference/get_post_meta?ref=kamilgrzegorczyk.com">get_post_meta()</a> uses  $single to retrieve only one record (if you expect only one record).</li>
<li><a href="https://codex.wordpress.org/Function_Reference/update_post_meta?ref=kamilgrzegorczyk.com">update_post_meta()</a> and <a href="https://codex.wordpress.org/Function_Reference/delete_post_meta?ref=kamilgrzegorczyk.com">delete_post_meta()</a> leverage $previous_value to ensure that you update/delete the key you want.</li>
</ul>
<p>Those parameters are helping in writing better, cleaner and more predictable code.</p>
<p>And that is not all. Use well tested, well written and extendable plugins like <a href="https://pods.io/?ref=kamilgrzegorczyk.com">Pods Framework</a> or <a href="https://www.advancedcustomfields.com/?ref=kamilgrzegorczyk.com">Advanced Custom Fields</a> to manage your custom fields. They are great when it comes to managing the tangled world of your custom data.</p>
<h3 id="summary">Summary</h3>
<p>In the ideal world you should always be aware of what you are adding into the system. You should know what your plugins, themes and custom functions are doing. That is unfortunately not always possible.</p>
<p>Therefore we should pay attention to the code we produce and tighten up all those loose ends.</p>
<p>That is all folks! I hope you liked it and have a great day!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Building Admin Columns Pro filters for ACF repeater fields]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Today&apos;s post is about how to filter your WordPress admin view based on ACF repater field value by building a plugin which extends Admin Columns Pro. Too much names? Let&apos;s head into the topic!</p>
<blockquote>
<p><strong>Update 8th of Nov 2017 to handle WP Core update to 4.</strong></p></blockquote>]]></description><link>https://kamilgrzegorczyk.com/2017/10/10/building-admin-columns-pro-filters-for-acf-repeater-fields/</link><guid isPermaLink="false">59dc5ad306281d115734f086</guid><category><![CDATA[wordpress]]></category><category><![CDATA[Advanced Custom Fields]]></category><category><![CDATA[react]]></category><category><![CDATA[Admin Columns Pro]]></category><dc:creator><![CDATA[Kamil Grzegorczyk]]></dc:creator><pubDate>Tue, 10 Oct 2017 12:59:23 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Today&apos;s post is about how to filter your WordPress admin view based on ACF repater field value by building a plugin which extends Admin Columns Pro. Too much names? Let&apos;s head into the topic!</p>
<blockquote>
<p><strong>Update 8th of Nov 2017 to handle WP Core update to 4.8.3</strong><br>
Thanks <a href="https://twitter.com/kokerss?ref=kamilgrzegorczyk.com">Kokers</a> for making me aware of changes in recent update ([Polish lang]dzi&#x119;ki :) [/Polish lang]).<br>
I went for the most straightforward fix but for anyone interested in solving it in more sophisticated way <a href="https://make.wordpress.org/core/2017/10/31/changed-behaviour-of-esc_sql-in-wordpress-4-8-3/?ref=kamilgrzegorczyk.com#comment-33136">here is the info on make.wordpress.org</a> and here you can find <a href="https://wordpress.stackexchange.com/questions/221760/how-do-i-query-for-posts-by-partial-meta-key/221766?ref=kamilgrzegorczyk.com#221766">a bit more advanced solution</a>.<br>
You can also use <code>remove_placeholder_escape</code> method but its only available from WP 4.8.3 - as this blog post is addressed to everyone (also poeple on older WP versions) I did not want to place this function here.<br>
We should wait for <a href="https://core.trac.wordpress.org/ticket/42409?ref=kamilgrzegorczyk.com">this ticket</a> to be merged into the core though. As soon as its incorporated into the core we could ditch all the hacky solutions alltogether.</p>
</blockquote>
<p>All of the code can be <a href="https://github.com/kamilgrzegorczyk/custom-ac-columns?ref=kamilgrzegorczyk.com">found on github</a>.</p>
<p>Big thank you to <a href="https://twitter.com/dungengronovius?ref=kamilgrzegorczyk.com">Stefan van den Dungen Gronovius</a>, one of Admin Columns Pro developers, who performed technical review of this article.</p>
<h3 id="intro">Intro</h3>
<p>Recently I was building a project in which I use WordPress as an CMS/API to feed small React application. The concept behind it is very simple and bases on REST API, built into the WordPress Core since few major versions.</p>
<p>The application data is stored in custom posts, <a href="https://www.advancedcustomfields.com/?ref=kamilgrzegorczyk.com">Advanced Custom Fields Pro</a> is used for handling all post metadata. Administration of the entries is handled through regular WordPress views.</p>
<p>As soon as the number of entries grew the need for better filtering and searching admin views started to arise. This problem could be easily solved with the help of <a href="https://www.admincolumns.com/?ref=kamilgrzegorczyk.com">Admin Columns Pro</a> which plays very nicely with ACF. The plugin gives you a possibility to add custom columns to your views. You can pick various types of columns: starting from simple fields like taxonomy, date, author to custom fields assigned to your CPT. What is even better - you can define filtering, sorting or inline-editing of the data in the column.</p>
<h3 id="filteringrepeaterfields">Filtering repeater fields</h3>
<p>As ACF repeater fields are complex and each repeater implementation is different there is no way to filter or sort those fields out of the box.</p>
<p>I was digging around ACF documentation and support forums with no success. Unfortunately Admin Columns docs were also silent about this. There was a <a href="https://github.com/codepress/ac-column-template?ref=kamilgrzegorczyk.com">starter template</a> showing how to build your custom column handling but without filter examples.</p>
<p>I had few ideas in my mind but all seemed hacky and I was thinking if there is a way to do it proper way.</p>
<p>While I was wondering if filtering of such fields is doable I have contacted <a href="https://twitter.com/dungengronovius?ref=kamilgrzegorczyk.com">Stefan van den Dungen Gronovius</a>, one of AC developers, who ensured me that this is possible and gave some very important tips.</p>
<h3 id="assumptions">Assumptions</h3>
<p>Before we start coding lets assume few things:</p>
<ul>
<li>We use most recent WordPress (4.8.2), Advanced Custom Fields (5.6.3) and Admin Columns Pro (4.0.10).</li>
<li>We have a Custom Post Types called <code>order</code> and <code>product</code>.</li>
<li>The <code>order</code> CPT contains a repeater field called <code>kg_order_items</code> which contains two fields: (1) relationship field (to <code>product</code> CPT) called <code>kg_order_item</code> and (2) a number field called <code>kg_order_quantity</code>.</li>
<li>What we are trying to achieve is to be able to filter the admin view of orders which contain particular product assigned to it.</li>
</ul>
<h3 id="thecode">The code</h3>
<p>We will be basing our solution on the aforementioned <a href="https://github.com/codepress/ac-column-template/?ref=kamilgrzegorczyk.com">starter template</a> so let&apos;s build a plugin first by creating a directory in <code>wp-content/plugins/custom-columns</code></p>
<p>Big thanks you for the Admin Columns development team for releasing the template!</p>
<h4 id="indexphp">index.php</h4>
<pre><code class="language-php">/*
Plugin Name:    Admin Columns - Filtering repeater fields
Plugin URI:     https://kamilgrzegorczyk.com
Description:    Handling filtering for custom repeater fields
Version:        1.0
Author:         Kamil Grzegorczyk
Author URI:     https://kamilgrzegorczyk.com
*/

//Registering the column for free version of the plugin. You won&apos;t be able to use filtering though!
add_action( &apos;ac/column_types&apos;, function ( AC_ListScreen $list_screen ) {

    // Use the type: &apos;post&apos;, &apos;user&apos;, &apos;comment&apos; or &apos;media&apos;.
    if ( &apos;post&apos; === $list_screen-&gt;get_meta_type() ) {
        require_once plugin_dir_path( __FILE__ ) . &apos;ac-column-assigned_products.php&apos;;
        $list_screen-&gt;register_column_type( new AC_Column_Assigned_Products() );
    }
});

//Registering the column for PRO version of the plugin
add_action( &apos;acp/column_types&apos;, function ( AC_ListScreen $list_screen ) {

    // Use the type: &apos;post&apos;, &apos;user&apos;, &apos;comment&apos; or &apos;media&apos;.
    if ( &apos;post&apos; === $list_screen-&gt;get_meta_type() ) {
        require_once plugin_dir_path( __FILE__ ) . &apos;ac-column-assigned_products.php&apos;;
        require_once plugin_dir_path( __FILE__ ) . &apos;acp-column-assigned_products.php&apos;;
        $list_screen-&gt;register_column_type( new ACP_Column_Assigned_Products );
    }
});
</code></pre>
<p>As our story goal is to make the column filterable therefore we can rely only on <code>acp/column_types</code> action. This is due to the face that filtering is available only in PRO version.<br>
I am adding <code>ac/column_types</code> action though (from the free version) just for the sake of promoting proper code structure (as each use case may be different and you may need it).</p>
<h4 id="accolumnassigned_productsphp">ac-column-assigned_products.php</h4>
<p>In this file we are going to define basic information about our column. Additonally, we are going to define how the data should be fetched and displayed.</p>
<p><strong>Class overview</strong></p>
<pre><code class="language-php">class AC_Column_Assigned_Products extends AC_Column {

    public function __construct() {

        // Identifier, pick an unique name. Single word, no spaces. Underscores allowed.
        $this-&gt;set_type( &apos;column-assigned-products&apos; );

        // Default column label.
        $this-&gt;set_label( __( &apos;Assigned products&apos;, &apos;ac-assigned-products&apos; ) );
    }

    public function get_value( $post_id ) {}

    public function get_raw_value( $post_id ) {}
}
</code></pre>
<p><strong>Data fetching</strong><br>
Now let&apos;s implement data fetching function which will read the products stored in our repeater field:</p>
<pre><code class="language-php">public function get_raw_value( $post_id ) {
    $products = get_field( &apos;kg_order_items&apos;, $post_id );
    $data       = [];

    if ( ! empty( $products ) ) {
        foreach ( $products as $product ) {
            $data[] = [
                &apos;id&apos;    =&gt; $product[ &apos;kg_order_item&apos; ]-&gt;ID,
                &apos;title&apos; =&gt; $product[ &apos;kg_order_item&apos; ]-&gt;post_title,
            ];
        }
    }

    return $data;
}
</code></pre>
<p><strong>Data display</strong><br>
Last part would be to handle the display of the values in the admin view. As mentioned before - each use case is different - for example in my personal projects I display the title of assigned item which links to the edit page.</p>
<pre><code class="language-php">public function get_value( $post_id ) {
    // get raw value
    $products = $this-&gt;get_raw_value( $post_id );

    $data = [];

    if ( ! empty( $products ) ) {
        foreach ( $products as $product ) {
            $data[] = &apos;&lt;a href=&quot;&apos; . esc_url( get_edit_post_link( $product[ &apos;id&apos; ] ) ) . &apos;&quot;&gt;&apos; . $product[ &apos;title&apos; ] . &apos;&lt;/a&gt;&apos;;
        }
    }

    return implode( &apos;,&lt;br&gt;&apos;, $data );
}
</code></pre>
<h4 id="acpcolumnassigned_productsphp">acp-column-assigned_products.php</h4>
<p>The last file which is going to contain the &quot;meat&quot; of our functionality.</p>
<p><em>The file is going to contain two classes which is contrary to best practice of having one class per file but it is a conscious decission for the sake of simplicity.</em></p>
<p><strong>Column Class</strong><br>
As we need only filtering therefore we implement only <code>ACP_Column_FilteringInterface</code>. If you need also sorting and editing you need to implement two additional interfaces (<code>ACP_Column_EditingInterface</code>, <code>ACP_Column_SortingInterface</code>).  Starter template contains an example of such scenario.</p>
<pre><code class="language-php">class ACP_Column_Assigned_Products extends AC_Column_Assigned_Products
    implements ACP_Column_FilteringInterface {

    public function filtering() {
        return new ACP_Filtering_Model_Assigned_Products( $this );
    }
}
</code></pre>
<p><strong>Model Class Overview</strong><br>
Model class tells the plugin how the filtering should be handled. There are many methods you may implement here but two of them are mandatory:</p>
<pre><code class="language-php">class ACP_Filtering_Model_Assigned_Products extends ACP_Filtering_Model {

    public function get_filtering_vars( $vars ) {}

    public function get_filtering_data() {}
}
</code></pre>
<p><strong>Fetching filter options</strong><br>
Now we need to supply the array of options which are going to be used to populate our filter. There are many ways to do it which depend on particular scenario.</p>
<p><em>Please have in mind that in many cases populating such filter may be very expensive process which may influence performance of admin pages</em>.</p>
<pre><code class="language-php">public function get_filtering_data() {
    return [
        &apos;order&apos;        =&gt; &apos;label&apos;,
        &apos;empty_option&apos; =&gt; false,
        &apos;options&apos;      =&gt; $this-&gt;get_products_for_dropdown(),
    ];
}

private function get_products_for_dropdown() {
    $args = [
        &apos;posts_per_page&apos; =&gt; -1,
        &apos;post_type&apos;      =&gt; &apos;product&apos;,
    ];
    $products_query = new \WP_Query( $args );
    $data             = [];

    if ( $products_query-&gt;have_posts() ) {
        while ( $products_query-&gt;have_posts() ) {
            $products_query-&gt;the_post();
            $data[ $products_query-&gt;post-&gt;ID ] = $products_query-&gt;post-&gt;post_title;
        }
        wp_reset_postdata();
    }

    return $data;
}
</code></pre>
<p><strong>Handling the filter values</strong><br>
Let&apos;s finish our functionality and tell WordPress how it should handle  filter values. For this purpose we are going to use function <code>get_filtering_vars</code> which exposes all query vars used to generate current admin screen.</p>
<p>Fetching repeater fields is a bit tricky but the whole process can be found in <a href="https://www.advancedcustomfields.com/resources/query-posts-custom-fields/?ref=kamilgrzegorczyk.com">ACF documentation</a> about &quot;sub custom field values&quot;.</p>
<p>More information on how to modify query vars can be found in <a href="https://codex.wordpress.org/Class_Reference/WP_Query?ref=kamilgrzegorczyk.com">WordPress Documentation page about WP Query Class</a></p>
<pre><code class="language-php">public function get_filtering_vars( $vars ) {

    add_filter( &apos;posts_where&apos;, function ( $where ) {
        $where = str_replace( &quot;meta_key = &apos;kg_order_items_&quot;, &quot;meta_key LIKE &apos;kg_order_items_&quot;, $where );

        return $where;
    } );

    $product_id = $this-&gt;get_filter_value();

    $vars[ &apos;meta_query&apos; ][] = [
        &apos;key&apos;     =&gt; &apos;kg_order_items_%_kg_order_item&apos;,
        &apos;compare&apos; =&gt; &apos;=&apos;,
        &apos;value&apos;   =&gt; $product_id,
    ];

    return $vars;
}
</code></pre>
<h3 id="laststepsandsummary">Last steps and summary</h3>
<p>After you finish your plugin you need to activate. Afterwards you need to configure columns set up at Admin Columns Pro settings page and add new column to <code>order</code> CPT listing view.</p>
<p>All of the code can be <a href="https://github.com/kamilgrzegorczyk/custom-ac-columns?ref=kamilgrzegorczyk.com">found on github</a><br>
If you have any questions please do not hesitate to contact me.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[How to retrieve location specific fields from Facebook Graph API]]></title><description><![CDATA[I am explaining how to retrieve location data (country code in particular) from Facebook Graph Api using one query.  ]]></description><link>https://kamilgrzegorczyk.com/2016/12/18/how-to-retrieve-location-specific-fields-from-facebook-graph-api/</link><guid isPermaLink="false">59b9205d8ff79062f02659e1</guid><category><![CDATA[development]]></category><category><![CDATA[facebook]]></category><dc:creator><![CDATA[Kamil Grzegorczyk]]></dc:creator><pubDate>Sun, 18 Dec 2016 16:28:44 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Recently I stumbled upon the small issue regarding the object returned by Facebook Graph API. Our app was relatively simple allowing us to get user age and location in order to determine whether user was allowed to see the site content or not.</p>
<p><a href="https://developers.facebook.com/docs/reference/php?ref=kamilgrzegorczyk.com">We used PHP SDK for that purpose</a> and fetched the data using <mark>get method</mark>. We wanted to get the information in <mark>one query for obvious performance reasons.</mark></p>
<p>Our get URL looked like</p>
<pre><code>/me?fields=age_range,location{location}
</code></pre>
<p>And response provided was something like (example simplified):</p>
<pre><code>&quot;age_range&quot;: { 
  &quot;min&quot;: &quot;21&quot;
},
&quot;location&quot;: {
  &quot;location&quot;: {
    &quot;city&quot;: &quot;some city&quot;,
    &quot;country&quot;: &quot;some location&quot;,
    &quot;latitude&quot;: 35.000,
    &quot;longitude&quot;: 15.123
  }
}
</code></pre>
<p>So everything nice and perfect? Not really.</p>
<p>Unfortunately we could not match country names with our internal system and location object from Facebook was not containing <mark>country ISO code</mark>. We were unable to modify our internal system records as it was used across many other systems.</p>
<p>Official <a href="https://developers.facebook.com/docs/graph-api/reference/location/?ref=kamilgrzegorczyk.com">Graph API documentation</a> was not providing any examples regarding how to fetch more information. Of course there was a way to make == 2 API calls == and then merge the information together but this wasn&apos;t something we were seeking for (performance, stupid).</p>
<p>As always in those kind of situations I have tried looking on Stack Overflow in case someone already had this issue before. Unfortunately answers were not helpful (<a href="http://stackoverflow.com/questions/9819310/is-it-possible-to-get-the-country-code-of-a-user-from-facebooks-graph-api?ref=kamilgrzegorczyk.com">this</a>, <a href="http://stackoverflow.com/questions/32046552/how-to-retrieve-user-country-using-facebook-graph-api?ref=kamilgrzegorczyk.com">that</a> or <a href="http://stackoverflow.com/questions/18586823/iso-country-code-for-facebook-users-location?ref=kamilgrzegorczyk.com">that one</a>) and still there was no solution to our issue.</p>
<p>With no more options on hand I started fooling around with the URL parameters. After short trial and error it worked! (you love that moment too, don&apos;t you? :) )</p>
<p>As it looks like the answer is pretty straightforward -&gt; <mark>You can nest your get parameters</mark> in order to fetch more properties of the objects.</p>
<p>By modifying URL to look like</p>
<pre><code>/me?fields=age_range,location{location{country_code}}
</code></pre>
<p>you can get the response which contains all needed information.</p>
<p>I hope that this helps someone!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Getting data from Advanced Custom Fields multi-value field]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><a href="https://www.advancedcustomfields.com/?ref=kamilgrzegorczyk.com">Advanced Custom Fields</a> is a great plugin for handling custom fields and field groups in WordPress.</p>
<p>It uses <code>wp_postmeta</code> table to store the data as  key in one column and value in second. This is not perfect but guarantees that the data is perfectly aligned with <em>&quot;the WordPress</em></p>]]></description><link>https://kamilgrzegorczyk.com/2016/11/17/getting-data-from-advanced-custom-fields-multi-value-field/</link><guid isPermaLink="false">59b9205d8ff79062f02659df</guid><category><![CDATA[wordpress]]></category><category><![CDATA[Short tips]]></category><category><![CDATA[development]]></category><category><![CDATA[Advanced Custom Fields]]></category><dc:creator><![CDATA[Kamil Grzegorczyk]]></dc:creator><pubDate>Thu, 17 Nov 2016 14:28:29 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1487058792275-0ad4aaf24ca7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDV8fGNvbXB1dGVyc3xlbnwwfHx8fDE2MTY5OTc4NDg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://images.unsplash.com/photo-1487058792275-0ad4aaf24ca7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDV8fGNvbXB1dGVyc3xlbnwwfHx8fDE2MTY5OTc4NDg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Getting data from Advanced Custom Fields multi-value field"><p><a href="https://www.advancedcustomfields.com/?ref=kamilgrzegorczyk.com">Advanced Custom Fields</a> is a great plugin for handling custom fields and field groups in WordPress.</p>
<p>It uses <code>wp_postmeta</code> table to store the data as  key in one column and value in second. This is not perfect but guarantees that the data is perfectly aligned with <em>&quot;the WordPress way&quot;</em> of storing custom fields.</p>
<p>Whenever there is a need to fetch posts based on custom field value one can use <code>WP_Query</code> parameters to get nice and easy results:</p>
<pre><code>&lt;?php
$posts = get_posts([
  &apos;meta_key&apos; =&gt; &apos;color&apos;,
  &apos;meta_value&apos; =&gt; &apos;red&apos;
]);
?&gt;
</code></pre>
<p>Situation complicates a bit when field can have multiple values (like relationship field, multi select) because then value is stored as serialized PHP array.</p>
<p>In this situation <a href="https://www.advancedcustomfields.com/resources/query-posts-custom-fields/?ref=kamilgrzegorczyk.com">official ACF documentation</a> points us towards using <code>LIKE</code> comparison which is unfortunately not a perfect example:</p>
<p><strong>Wrong (official) way:</strong></p>
<pre><code>&lt;?php
$posts = get_posts([
  &apos;meta_query&apos; =&gt; [
    &apos;relation&apos; =&gt; &apos;OR&apos;,
      [
        &apos;key&apos;     =&gt; &apos;location&apos;,
        &apos;value&apos;   =&gt; &apos;Melbourne&apos;,
        &apos;compare&apos; =&gt; &apos;LIKE&apos;,
      ],
      [
        &apos;key&apos;     =&gt; &apos;location&apos;,
        &apos;value&apos;   =&gt; &apos;Sydney&apos;,
        &apos;compare&apos; =&gt; &apos;LIKE&apos;,
      ],
  ]
]);
?&gt;
</code></pre>
<p>Why is it wrong? Because it will match posts with location set to &quot;Sydney&quot; as well as &quot;Sydney123&quot;.</p>
<p>While it looks like made up issue it becomes dangerous when using <code>[ key=&gt; &apos;id&apos;, value=45]</code> == would match id value of 45,456,145 etc.== which stops being funny.</p>
<p><strong>Proper way:</strong></p>
<pre><code>&lt;?php
$id = 45;
$posts = get_posts([
  [...],
  &apos;meta_query&apos; =&gt; [
    [...],
    [
      &apos;key&apos;     =&gt; &apos;id&apos;,
      &apos;value&apos;   =&gt; &apos;&quot;&apos;. $id .&apos;&quot;&apos;,
      &apos;compare&apos; =&gt; &apos;LIKE&apos;,
    ]
  ]
]);
?&gt;
</code></pre>
<p>As mentioned before - multiple values are stored as serialized PHP array looking similar to<br>
<code>a:3:{i:0;s:4:&quot;Math&quot;;i:1;s:8:&quot;Language&quot;;i:2;s:7:&quot;Science&quot;;}</code></p>
<p>Adding quotes around a value (&quot;45&quot; instead 45) matches the way serialized array values are stored in DB and gives us proper results.</p>
<p><mark>Please have in mind</mark> that this method works only if we are storing data in proper way (no white space or weird encoding). To make sure use any MYSQL administration tool like MYSQL Workbench or PHPMyAdmin and see how particular field value is being stored in DB.</p>
<p>I hope that this helps someone. In case of any questions feel free to use comments below.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Code inspection for zero width non-printable chars]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><strong>Warning:</strong> This post covers scenarios when non-printable characters are entered by you during development process. <mark>Sanitization of user or 3rd party API input is a completely different topic.</mark></p>
<p>Welcome to the world of non-printable UTF-8 characters. They are easy to miss in the editor and can cause various issues in</p>]]></description><link>https://kamilgrzegorczyk.com/2016/11/04/code-inspection-for-zero-width-non-printable-chars/</link><guid isPermaLink="false">59b9205d8ff79062f02659dc</guid><category><![CDATA[development]]></category><category><![CDATA[tools]]></category><dc:creator><![CDATA[Kamil Grzegorczyk]]></dc:creator><pubDate>Fri, 04 Nov 2016 14:28:11 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><strong>Warning:</strong> This post covers scenarios when non-printable characters are entered by you during development process. <mark>Sanitization of user or 3rd party API input is a completely different topic.</mark></p>
<p>Welcome to the world of non-printable UTF-8 characters. They are easy to miss in the editor and can cause various issues in the code. Especially when using the same text string in different languages which treat them in their own way.</p>
<h4 id="examples">Examples</h4>
<p>Most common non-printable Unicode characters which you may encounter are:</p>
<ul>
<li>\u200b: zero width space</li>
<li>\u200c: zero width non-joiner</li>
<li>\u200d: zero width joiner</li>
<li>\ufeff: zero width no-break space</li>
<li>\u2028: line separator</li>
<li>\u2029: paragraph separator</li>
</ul>
<h3 id="whatarethedangers">What are the dangers?</h3>
<p>There are multiple issues which occur, their severity level depends on the context in which those characters exist in the code.</p>
<h5 id="javascript">JavaScript</h5>
<p>Due to some design inconsistencies line and paragraph separators are perfectly valid characters in JSON world but will cause a <code>SyntaxError: Unexpected token ILLEGAL</code> when used in JavaScript.</p>
<p>Modern browsers and JSON parsing libraries have methods to overcome that issue but you can still introduce it easily by passing variables from PHP (or other backend language) to JS by using common <code>var x = &apos;&lt;?= $php_var;?&gt;&apos;;</code> method.</p>
<p>If you are interested to read more please visit this <a href="http://timelessrepo.com/json-isnt-a-javascript-subset?ref=kamilgrzegorczyk.com">great article about JavaScript and JSON</a></p>
<p>Example above is just a tip of an iceberg as errors may vary depending on the context in which those characters exist. Try to search for &quot;non-printable characters&quot; at StackOverflow and you can get more than <a href="http://stackoverflow.com/search?q=non-printable+characters&amp;ref=kamilgrzegorczyk.com">2,000 results</a>.</p>
<h5 id="htmlcss">HTML/CSS</h5>
<p>Alternatively if those characters end up in template you may see various <mark>styling issues</mark> -  those characters are most of the time properly rendered by browser so do not be surprised from having weird gaps when there is &quot;nothing&quot; in CSS and there is no visible markup. Simply browser can interpret your invisible <code>\u2028\</code> character as regular line break and apply spacing in there.</p>
<h3 id="howtheylandedinmycode">How they landed in my code?</h3>
<p>It is difficult to enter them on purpose but it is very easy to introduce those characters via simple <mark>copy-paste</mark>. Most of the common sources might be a PDF, MSWord document or simple output of Google Chrome Developer Tools edit HTML mode.</p>
<h3 id="howtospotthemoutsideeditor">How to spot them outside editor?</h3>
<p>If you are very lucky and the error exists only in HTML then you might spot <mark>red dots</mark> in Chrome Dev Tools (edit HTML mode) which are representing non-printable characters.<br>
<img src="https://kamilgrzegorczyk.com/content/images/2016/11/Screen-Shot-2016-11-04-at-12.34.21.png" alt loading="lazy"></p>
<p>There is also chance that the browser will output some weird characters to the screen indicating that there is an issue. That may depend on browser encoding settings, used fonts or placement of such character.<br>
<img src="https://kamilgrzegorczyk.com/content/images/2016/11/Screen-Shot-2016-11-04-at-11.56.16.png" alt loading="lazy"></p>
<p>If you are less lucky though then you may get weird, uncommon <code>SyntaxError: Unexpected token ILLEGAL</code> JavaScript errors. If there is no clear and visible syntax issue in the code then it <mark>may</mark> be caused by aforementioned non-printable characters.</p>
<h4 id="howtosolveit">How to solve it?</h4>
<p>Some of the editors have possibility to highlight non-printable characters by adjusting its settings.</p>
<p>If you use the one and only PHPStorm (as me) then Victor Rosenberg wrote a plugin called <mark>Zero width character locator</mark> which scans your code in order to detect various &quot;sneaky little bastards&quot;. The plugin can be downloaded from the link below or installed directly from PHPStorm settings.<br>
<a href="http://plugins.jetbrains.com/plugin/7448?ref=kamilgrzegorczyk.com">http://plugins.jetbrains.com/plugin/7448</a></p>
<p>Activate it and voil&#xE0; - you have the inspection results directly in your code editor window. If that is not enough then you have also a possibility to scan complete project directory and find all problematic occurrences.</p>
<p>After fixing the issue you may notice the difference in <code>git diff</code> output:<br>
<img src="https://kamilgrzegorczyk.com/content/images/2016/11/Screen-Shot-2016-11-04-at-12.35.00.png" alt loading="lazy"></p>
<p>I hope that this helps someone. Let me know if you have any questions!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Flushing DNS in MacOS Sierra]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>If you would need to flush DNS cache in newest OSX from Cuppertino you can use same command as before:</p>
<p><code>sudo killall -HUP mDNSResponder</code></p>
<p>But what if your DNS is resolving properly but in you browser you see wrong results? As it occurs browser may keep its own DNS cache</p>]]></description><link>https://kamilgrzegorczyk.com/2016/11/02/flushing-dns-in-macos-sierra/</link><guid isPermaLink="false">59b9205d8ff79062f02659da</guid><category><![CDATA[Short tips]]></category><dc:creator><![CDATA[Kamil Grzegorczyk]]></dc:creator><pubDate>Wed, 02 Nov 2016 21:02:32 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>If you would need to flush DNS cache in newest OSX from Cuppertino you can use same command as before:</p>
<p><code>sudo killall -HUP mDNSResponder</code></p>
<p>But what if your DNS is resolving properly but in you browser you see wrong results? As it occurs browser may keep its own DNS cache which may sometimes go against your efforts.</p>
<p>To clean DNS cache in Chrome you need to navigate to:</p>
<p><code>chrome://net-internals/#dns</code></p>
<p>and press &quot;Clear host cache&quot; button.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Lets start! Ghost, here we come!]]></title><description><![CDATA[First post of new incarnation of my blog about technology, programming and other things I breathe with everyday.]]></description><link>https://kamilgrzegorczyk.com/2016/11/02/lets-start-ghost-here-we-come/</link><guid isPermaLink="false">59b9205d8ff79062f02659d8</guid><dc:creator><![CDATA[Kamil Grzegorczyk]]></dc:creator><pubDate>Wed, 02 Nov 2016 20:04:32 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Well... this is not how I have envisioned it before but...</p>
<p>You know that ideas are nothing because execution is the king?</p>
<p>And yes - unfortunately having perfectionist character and plenty of ideas ended up in me setting up my blog for 18 months. Without any visible progress.</p>
<p>Same thing also happened to many other ideas of mine. Those died simply because they were too time consuming, too complicated to make them in a way which would please me (read =&gt; never).</p>
<p>That is why I decided to stop all of this bullshit about choosing pixel perfect theme template, setting up crazy WordPress install with gazillion of options and all of this fanciness.</p>
<p>I have chosen Ghost, NodeJS based CMS which I have backed up as Kickstarter project many years ago.</p>
<p>Why?</p>
<p>Because I wanted to try something new. On everyday basis I manage few WordPress sites, I work in WordPress, I read about WordPress, I write extensions and themes for it. Ghost seems to be something which will take me away from it and let me concentrate on producing content. Something which should be actually most important.</p>
<p>So lets start and try to figure out thing on the way!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>