<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>WPlancer</title>
	<atom:link href="https://wplancer.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://wplancer.com</link>
	<description>WordPress and WooCommerce Developer</description>
	<lastBuildDate>Fri, 20 Oct 2023 07:51:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://wplancer.com/wp-content/uploads/2023/08/wplancer-wordpress-freelancer-logo-150x150.png</url>
	<title>WPlancer</title>
	<link>https://wplancer.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Debug WordPress Like a PRO</title>
		<link>https://wplancer.com/wordpress-debug-log/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Wed, 04 Oct 2023 10:04:26 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=3113</guid>

					<description><![CDATA[If you build or maintain WordPress websites, sooner or later you will run into issues. There are many ways to go about debugging in WordPress, but there it is how the professionals do it. Activate debug log Turning on debug mode and displaying the errors on frontend is one ugly business. It&#8217;s neither easy to [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>If you build or maintain WordPress websites, sooner or later you will run into issues. There are many ways to go about debugging in WordPress, but there it is how the professionals do it.</p>



<h2 class="wp-block-heading"><strong>Activate debug log</strong></h2>



<p>Turning on debug mode and displaying the errors on frontend is one ugly business. It&#8217;s neither easy to use nor aesthetically pleasing. And it&#8217;s a big no-no if your site is live. So, what the professional does is <strong>logs the errors</strong>, especially if you don&#8217;t have access to the main web server logs.</p>



<p>To enable the debug mode logs in WordPress, you add the following lines to your <code>wp-config.php</code>. </p>



<pre class="wp-block-code"><code lang="php" class="language-php">define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );</code></pre>



<h2 class="wp-block-heading">View the logs in real time</h2>



<p>The WordPress debug log location is <code>wp-content/debug.log</code>. It saves all errors, warnings and notices in there. Now you can see the issues in real time as they happen by using this <code>tail</code> Linux command:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">tail -f wp-content/debug.log</code></pre>



<h2 class="wp-block-heading">Custom logs</h2>



<p>Debug logging is very handy when you build your own stuff. When you have things you need to dig deep into actions and filters,especially AJAX ones, there is no direct way to display them in the screen, so you log them like a PRO.</p>



<pre class="wp-block-code"><code lang="php" class="language-php">error_log( $var_to_debug );</code></pre>



<p>It will log the whatever you pass to the function to same <code>debug.log</code> file. As a results, you won&#8217;t lose a single hair out of debugging despair.</p>



<p><code>error_log()</code> only logs strings, so if you want to debug an array or object, you&#8217;ll have to run it through <code>print_r()</code> first and then return it to <code>error_log()</code>. Like this:</p>



<pre class="wp-block-code"><code lang="PHP" class="language-PHP">error_log( print_r( $var_to_debug, true ) );</code></pre>



<p>Stop debugging like an amateur and start doing it like a PRO!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Check If Post Slug Exists</title>
		<link>https://wplancer.com/post-slug-exists/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Fri, 07 Apr 2023 02:01:22 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=2790</guid>

					<description><![CDATA[In the rare cases when you need to check if a post exists by slug, here goes a function to handle that. Note that the slug in WordPress is internally referred as post_name. Include the function below in your WordPress project. You can add it to your functions.php file in your theme or any file [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In the rare cases when you need to check if a post exists by slug, here goes a function to handle that. Note that the <em>slug</em> in WordPress is internally referred as <em>post_name</em>.</p>



<p>Include the function below in your WordPress project. You can add it to your <code>functions.php</code> file in your theme or any file in a custom plugin you&#8217;re building. </p>



<p>The function will return the found post ID, if a post with the given slug is found, or otherwise <code>false</code>.</p>



<pre title="" class="wp-block-code"><code lang="php" class="language-php line-numbers">function post_slug_exists( $post_name ) {
	global $wpdb;
	if ( $p = $wpdb-&gt;get_row( "SELECT ID, post_name FROM {$wpdb-&gt;prefix}posts WHERE post_name = '" . $post_name . "'" ) ) {
		return $p-&gt;ID;
	} else {
		return false;
	}
}</code></pre>



<p>Once the function is included, you can use it to check whether a post with a particular slug exists in the database. In my case, I needed to delete the original post before syncing the same post again.</p>



<pre title="" class="wp-block-code"><code lang="php" class="language-php line-numbers">if ( $pid = post_slug_exists( $post-&gt;post_name ) ) {
    // Delete this line and do your thing
    wp_delete_post( $pid, true );
}</code></pre>



<p>Keep building!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Find Posts with the Most Number of Revisions</title>
		<link>https://wplancer.com/posts-revisions-count/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Fri, 12 Feb 2016 07:23:03 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=1959</guid>

					<description><![CDATA[I was working on a content-heavy website that have a very big wp_posts table. This obviously caused by a revisions. To confirm this I needed to find out which where the posts with the most number of revisions. As I had guessed, I found out revisions where killing the wp_posts table. Quite a few posts [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>I was working on a content-heavy website that have a very big <code>wp_posts</code> table. This obviously caused by a revisions. To confirm this I needed to find out which where the posts with the most number of revisions. As I had guessed, I found out revisions where killing the <code>wp_posts</code> table. Quite a few posts had as many as 100+ revisions.</p>



<p>To find this out I came up with this SQL query then I ran in <a href="https://www.phpmyadmin.net/" rel="noopener">phpMyAdmin</a>:</p>



<pre class="wp-block-code"><code lang="sql" class="language-sql">SELECT parent.ID, parent.post_title, count(children.post_parent) AS children_count 
  FROM wp_posts as parent
LEFT OUTER
  JOIN wp_posts as children
    ON children.post_parent = parent.ID &amp;&amp; children.post_type = 'revision'
  WHERE parent.post_parent = 0
GROUP
    BY parent.ID
ORDER BY children_count DESC
LIMIT 50</code></pre>



<p>Of course, the first thing I did after I found this out was limiting the revisions in WP by putting this line in <code>wp-config.php</code></p>



<pre class="wp-block-code"><code lang="php" class="language-php">define('WP_POST_REVISIONS', 2);</code></pre>



<p>I highly recommend doing this for content-heavy WordPress sites.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Assign Authors or Co-authors to a WordPress Posts Programmatically</title>
		<link>https://wplancer.com/assign-authors-programmatically/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Wed, 18 Nov 2015 17:27:02 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Authors]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=1927</guid>

					<description><![CDATA[There are occasions when you need to do something programmatically, i.e., through a little function, rather then by clicking on a button in WordPress. Such was the case when I needed to re-assign an author to massive amount of posts. There were just too many posts to do it manually from the backend of WordPress, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>There are occasions when you need to do something programmatically, i.e., through a little function, rather then by clicking on a button in WordPress. Such was the case when I needed to re-assign an author to massive amount of posts. There were just too many posts to do it manually from the backend of WordPress, so I had to accomplish this through a little piece of code.<span id="more-1927"></span></p>
<h2>Assigning an author</h2>
<p>To assign a single author to a post or a list of posts running them through a loop, the core code would look like this.</p>
<pre data-language="php">// Prepare data
$p = array(
    'ID'          =&gt; $post_id,
    'post_author' =&gt; $auth_id
);

// Save data
wp_update_post( $p );</pre>
<p>This code will update the author with the given <code>$auth_id</code> value, which is the desired user ID in WordPress.</p>
<h2>Assigning co-authors</h2>
<p>After the first tests with the above script, I discovered that it was not of much help because we were using the <a href="https://wordpress.org/plugins/co-authors-plus/" target="_blank" rel="noopener">Co-Authors Plus</a> plugin, which did not update its data when post authors was updated programmatically. So, I had to figure out how to accomplish this for co-authors instead.</p>
<p>After doing some digging on the plugin codebase, I discovered that they expose an <code>object</code> as global by the name of <code>$coauthors_plus</code> which we can call from our function. The core code will look like this:</p>
<pre data-language="php">// Prepare data
$coauthors = array($auth_username);

// Save data
$coauthors_plus-&gt;add_coauthors($post_id, $coauthors);</pre>
<p>Running <code>add_coauthors()</code> method takes care of all the necessary steps to assign the co-authors. We can pass one or more co-authors at the same time as an array, but this time we don&#8217;t pass the user IDs, but their usernames instead. This is how this plugin saves the co-authors data.</p>
<p>These are the ways to programmatically assign authors and co-authors in WordPress. Please let me know in the comments if you found this helpful or need further explanation on this subject. Keep learning!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Overwrite Default Post Permalinks</title>
		<link>https://wplancer.com/overwrite-permalink/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Fri, 13 Nov 2015 06:12:44 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Hooks]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=1905</guid>

					<description><![CDATA[Every WordPress post has a permalink by default. The permalink is displayed, as expected, by the the_permalink() function. In some cases, we might need to enforce another URL to a post as its permalink, be it another link within the site or an external URL. We can provide the custom URL through a custom field [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Every WordPress post has a permalink by default. The permalink is displayed, as expected, by the <code>the_permalink()</code> function. In some cases, we might need to enforce another URL to a post as its permalink, be it another link within the site or an external URL. We can provide the custom URL through a custom field that we will conveniently name <code>overwrite_permalink</code>.</p>
<p><span id="more-1905"></span>Before you think of polluting your theme files with those nasty conditionals, think again. What we will be using to achieve this is a custom function that we are going to <a href="https://wplancer.com/wordpress-hooks/">hook into WordPress</a> through the <code>the_permalink</code> and the <code>the_permalink_rss</code> filters. The first one will take care of the user-facing website and the other will handle RSS readers, so that we can have a consistent experience everywhere. This filters allow us to make the change in just once place, instead of making a mess of all our theme files.</p>
<p>Check the end result below:</p>
<pre data-language="php">function ns_overwrite_permalink($permalink)
{
    if( $custom = get_post_meta(get_the_ID(), 'overwrite_permalink', true) ) {
        $permalink = $custom;
    }
    return $permalink;
}
add_filter('the_permalink', 'ns_overwrite_permalink');
add_filter('the_permalink_rss', 'ns_overwrite_permalink');</pre>
<p>This code goes into the <code>functions.php</code> file and no other change is needed anywhere. Such is the power of WordPress hooks, so <a href="https://wplancer.com/wordpress-hooks/">learn to leverage them</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A Guide to Actions and Filters in WordPress</title>
		<link>https://wplancer.com/wordpress-hooks/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Mon, 09 Nov 2015 19:24:33 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Hooks]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=1853</guid>

					<description><![CDATA[WordPress comes with this built-in API that allows us to hook custom functionality into the rest of WordPress. We can provide that extra functionality through plugins or themes. These are called hooks and they are either actions or filters.&#160; Actions allow us to run custom functions at a certain points of a request, while filters [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>WordPress comes with this built-in API that allows us to hook custom functionality into the rest of WordPress. We can provide that extra functionality through plugins or themes. These are called <em>hooks</em> and they are either <em>actions</em> or <em>filters</em>.&nbsp; <em>Actions</em> allow us to run custom functions at a certain points of a request, while <em>filters</em> allow us to process and change&nbsp;<em>data</em> at these certain points.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>The gist of the difference between <em>actions</em> and <em>filters</em> is: <br><em>Actions</em> modify <strong>functionality</strong>; <em>filters</em> modify <strong>data</strong>.</p>
</blockquote>



<span id="more-1853"></span>



<p>WordPress makes heavy use of <em>actions</em> and <em>filters</em> for its own core functionality. Thus, we can use <em>actions</em> and <em>filters</em> to modify WordPress default functionality&nbsp; or add our own on top of it. WordPress ships with an extensive lists of <a href="http://codex.wordpress.org/Plugin_API/Action_Reference" target="_blank" rel="noopener">actions</a> and <a href="http://codex.wordpress.org/Plugin_API/Filter_Reference" target="_blank" rel="noopener">filters</a> that we, as developers, need to accustom ourselves with.</p>



<h2 class="wp-block-heading">Usage</h2>



<p>To employ <em>actions</em> and <em>filters</em> we need to use these two functions: <code>add_action()</code> and <code>add_filter()</code>. Both of them take four same arguments. The first two arguments are required and the two others are not and we won&#8217;t find ourselves using them a lot.</p>



<p>We hook custom functionality into WordPress like this:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">add_action( 'hook_name', 'our_custom_action', [priority], [accepted_args] );</code></pre>



<p>We use custom filters to transform data passed through WordPress like this:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">add_filter( 'hook_name', 'our_custom_filter', [priority], [accepted_args] );</code></pre>



<h2 class="wp-block-heading">Actions</h2>



<p>Actions are triggered at specific times during the request. In front-end it can be the time when the header or footer is loaded, giving us the ability to put our scripts at those sections. In back-end it can be the time when a post is published so that we can email our subscribers to notify them that a new post is published on our blog.</p>



<p>In the example <em>action</em> below the function changes default WordPress functionality by modifying the default image link type. By default it is set to <em>Media File</em> and we want it to default to <em>None</em> so we can save a couple of clicks when we insert images into a post. We <em>hook</em> this functionality in the <code>admin_init</code> action, which runs before any other hook when a user accesses the admin area.</p>



<pre class="wp-block-code"><code lang="php" class="language-php line-numbers">function wpl_image_link_type() {
	$image_set = get_option( 'image_default_link_type' );

	if ( $image_set != 'none' ) {
		update_option( 'image_default_link_type', 'none' );
	}
}
add_action( 'admin_init', 'wpl_image_link_type' );</code></pre>



<p>In such a fashion we run every action to modify WordPress default functionality or to add extra functionality to it.</p>



<h2 class="wp-block-heading">Filters</h2>



<p>Filters are functions which modify <em>data</em> that WordPress passes through them before showing that data to the user or inserting it into the database. Filters take in data and modify it and then return it so other filters can continue to process it.</p>



<p>In the example <em>filter</em> below, it default data by modifying the classes added to body by default through the <code>body_class()</code> function. Through this filter we append a class name to the list of default classes. Our theme relays on this class for showing the right color scheme based on what the user has saved in theme Customizer, i.e. either <em>light</em> or <em>dark</em>.</p>



<pre class="wp-block-code"><code lang="php" class="language-php line-numbers">function wpl_body_class( $classes ) {
	// light or dark color scheme
	$classes[] = get_theme_mod( 'color-scheme', 'light' );

	return $classes;
}
add_filter( 'body_class', 'wpl_body_class' );</code></pre>



<p>This is the way to filter data in WordPress. It&#8217;s very similar in structure to <em>actions</em>.</p>



<h2 class="wp-block-heading">Custom Actions and Filters</h2>



<p>Up to now we have talked about how we can use <em>actions</em> and <em>filters</em> that ship with WordPress. However, WordPress allows us to create our own actions and filters through plugins and themes. Custom actions and filters are helpful to make our themes and plugins extendible through child themes or other plugins without needing the edit the source files.</p>



<p>Custom actions and filters are created and called in the same way that core WordPress hooks are, through <code>do_action()</code> and&nbsp;<code>apply_filters()</code>.</p>



<p>In the sample <em>custom action hook</em> below we want to add extra elements after the post content, we can add an <em>action hook</em> in our appropriate theme file like this:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">do_action('after_content');</code></pre>



<p>To hook into that <em>action</em>, so that we can, for example, show author bios or other elements like ads, we will have to run something like this:</p>



<pre class="wp-block-code"><code lang="php" class="language-php line-numbers">function wpl_author_byline() {
	get_template_part( 'parts/author', 'byline' );
}
add_action( 'after_content', 'wpl_author_byline' );</code></pre>



<p>On the other hand, for our <em>custom filter hook</em>, let&#8217;s say we want to add more color schemes to our default ones, <em>dark </em>and <em>light</em> that we talked above. In this case we want the default list of colors schemes to be extendible through a child theme. We will have have to create a <em>custom filter hook </em> like this:</p>



<pre class="wp-block-code"><code lang="php" class="language-php line-numbers">function wpl_color_schemes() {
	$color_schemes = [ 
		'light' => 'Light',
		'dark' => 'Dark'
	];

	return apply_filters( 'wpl_schemes_filter', $color_schemes );
}</code></pre>



<p>To hook into this filter and expend the list with more color schemes, we run something like this:</p>



<pre class="wp-block-code"><code lang="php" class="language-php line-numbers">function wpl_add_color_schemes( $color_schemes ) {
	$color_schemes['yellow'] = 'Yellow';
	$color_schemes['blueish'] = 'Blueish';

	return $color_schemes;
}
add_filter( 'wpl_schemes_filter', 'wpl_add_color_schemes' );</code></pre>



<p>The end result will be that on our Customizer now will show four color schemes rather then the original two.</p>



<p>Custom <em>hooks</em> into our themes or plugins make our code extensible so that we, or others, can modify and extend.</p>



<h2 class="wp-block-heading"><strong>Keep learning</strong></h2>



<p><em>Actions</em> and <em>filters</em> are a powerful tool at the hand of the developer and a great way to modify default WordPress functionality and to extend it. I  hope this article has taught you something new and valuable for your everyday work.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Get Post Slug in WordPress</title>
		<link>https://wplancer.com/get-post-slug/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Sun, 01 Nov 2015 14:40:09 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Post Slug]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=1799</guid>

					<description><![CDATA[The post slug is the part of the URL of a post or page at the last section. E.g.: Page: https://wplancer.com/about/Post: https://wplancer.com/2015/09/post-slug-here/ There are two ways to get the slug in WordPress inside the loop. The first way is to access the $post object that is available inside the loop. The second way is to [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>The post slug is the part of the URL of a post or page at the last section. E.g.:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Page: https://wplancer.com/<strong>about</strong>/<br>Post: https://wplancer.com/2015/09/<strong>post-slug-here</strong>/</p>
</blockquote>



<p>There are two ways to get the slug in WordPress inside the loop. The first way is to access the <code>$post</code> object that is available inside the loop.</p>



<pre class="wp-block-code"><code lang="php" class="language-php">$slug =  $post->post_name;</code></pre>



<p>The second way is to pass the whole permalink to the <code><a href="https://www.php.net/basename" rel="noopener">basename</a></code> function, which will automatically process the URL and give us only the slug.</p>



<pre class="wp-block-code"><code lang="php" class="language-php">$slug = basename(get_permalink());</code></pre>



<p>Use the way that makes most sense to you to get the post slug in WordPress. Keep building!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PHPloy &#8211; Deploy Git Repos Easily through FTP/sFTP</title>
		<link>https://wplancer.com/phploy/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Mon, 10 Feb 2014 18:26:17 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[FTP]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[SFTP]]></category>
		<category><![CDATA[SSH]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=1585</guid>

					<description><![CDATA[Let me ask you a question: How mad do you get when you have to remember which files you edited and select them on FileZilla to upload to the server? That&#8217;s right &#8211; very mad. And sometimes you just upload the whole project because you don&#8217;t remember what you edited. I have four words for [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Let me ask you a question: How mad do you get when you have to remember which files you edited and select them on FileZilla to upload to the server? That&#8217;s right &#8211; very mad. And sometimes you just upload the whole project because you don&#8217;t remember what you edited. I have four words for that: &#8220;Been there; done that&#8221;.<span id="more-1585"></span></p>
<p>Out of that frustration I set out to find a script that would use <a title="Git Version Control System" href="https://wplancer.com/tag/git" target="_blank">Git</a> to determine which files I had edited, since this is what Git does best, and <strong>upload those to the server through FTP.</strong> I used a <a title="git ftp" href="https://github.com/git-ftp/git-ftp" target="_blank" rel="noopener">bash script</a> for some times. But that script was a bit sloppy and not very user friendly. I searched again for something written in PHP and I found a <a title="git deploy php" href="https://github.com/BrunoDeBarros/git-deploy-php" target="_blank" rel="noopener">great little script</a> that worked great. I used it for a long time as-is. Then I needed it to support Git submodules, which it did not, and so I added that functionality and made many more improvements. Now again I needed it to support nested submodules, or in other words, submodules inside submodules, and now it it has that functionality in place too.</p>
<p>So, it seemed a great time to make that little script public. I&#8217;ve named it <a title="PHPloy - PHP Git Deployment" href="https://github.com/banago/PHPloy" target="_blank" rel="noopener">PHPloy</a>, and it does very well what it says. It is a little PHP script that allows you to deploy files through FTP to a server. It makes use of Git to know which files it should upload and which one it should delete. It is a real time-saver.</p>
<h2>How it works</h2>
<p>PHPloy is very easy to use. After you have committed your changes in Git and have configured your server(s) in <code>deploy.ini</code>, all you have to do is run:</p>
<pre data-language="shell">phploy</pre>
<p>If you want to specify a server, you run:</p>
<pre data-language="shell">phploy -s staging</pre>
<p>Or the long form:</p>
<pre data-language="shell">phploy --server staging</pre>
<p>There is a lot more fun stuff that you can check in the <a title="PHPloy - Git FTP Deployment" href="https://github.com/banago/PHPloy" target="_blank" rel="noopener">project page in Github</a>.</p>
<h2>Behind the scene</h2>
<p>PHPloy stores a file called <code>.revision</code> on the server. This file contains the hash of the commit that you have deployed to that server. When you run PHPloy, it downloads that file and compares the commit reference in it with the commit you are trying to deploy to find out which files to upload.</p>
<h2>Grab it</h2>
<p>Head over to <a title="PHPloy - Git FTP Deployment" href="https://github.com/banago/PHPloy" target="_blank" rel="noopener">PHPloy&#8217;s Github page</a> to download it and learn more how to use it.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introduction to Subversion</title>
		<link>https://wplancer.com/how-to-install-and-use-svn/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Mon, 03 Feb 2014 09:58:49 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Version Control]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=1568</guid>

					<description><![CDATA[On my previous post I wrote about installing and configuring Git because I&#8217;m really a Git guy, but I have this client now that prefers SVN, short of Subversion version control system, so I had to learn it too. In this post I&#8217;m going to introduce you to SVN and how to get it to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>On my previous post I wrote about <a title="How to Install and Configure Git on Ubuntu" href="https://wplancer.com/how-to-set-up-git-on-ubuntu/">installing and configuring Git</a> because I&#8217;m really a Git guy, but I have this client now that prefers <a title="SVN" href="http://subversion.apache.org/" target="_blank" rel="noopener">SVN</a>, short of <a title="Subversion" href="http://subversion.apache.org/" target="_blank" rel="noopener">Subversion</a> version control system, so I had to learn it too. In this post I&#8217;m going to introduce you to SVN and how to get it to work. But first, how does it compare to Git?<span id="more-1568"></span></p>
<p>The main difference of Git and Subversion is that Subversion is centralized; everything happens in a repository on a server, thus you have to be online in order to do anything with SVN at all. On the other hand, Git is decentralized. You have a full copy of what is in the server and can do anything with it offline, and push changes to the server whenever you want. There are also other differences on how they handle tracking of changes, but that&#8217;s not the point of this post.</p>
<h2>Installation</h2>
<p>To install Subversion or otherwise SVN on your computer, if you are running <a title="Ubuntu" href="https://wplancer.com/tag/ubuntu/">Ubuntu</a> as me, all you have to do is  run this command on the <a title="Introduction to terminal" href="https://wplancer.com/a-beginners-guide-to-the-command-line/" target="_blank">terminal</a>:</p>
<pre>sudo apt-get install subversion</pre>
<p>That&#8217;s it for installing.</p>
<h2>Connect to SVN</h2>
<p>Now, to start working with it, it means that someone has set up SVN on a server somewhere and you are given an SVN repository URL that you can <code>checkout</code>, which means you fetch the repository contents and meta-data to your local machine. To do that you run:</p>
<pre>svn checkout svn://example.com/repopath/reponame</pre>
<p>Depending on whether or not the server has you ssh public key, you might be prompted for a username and password. Just enter those to continue.</p>
<h3>Check status</h3>
<p>The point of version control systems is that it keeps track of your work. After you have made some changes to the files you got from the server and added new files and deleted others, to check what files you have changed you you have to enter your working directory by running <strong><code>cd reponame</code></strong> and then run:</p>
<pre>svn status</pre>
<p>To actually see what content you have added or deleted on those files your run:</p>
<pre>svn diff</pre>
<h2>Commit Changes</h2>
<p>To send the changes you have done to the repository, all you have to do is run:</p>
<pre>svn commit -m 'What did you change and why message'</pre>
<p>As I told you above, you cannot run this command if you are not connected to the Internet. Remember, SVN is centralized &#8212; everything has to happen on the server.</p>
<h2>Fetch Changes</h2>
<p>To get changes other fellow developers might have done to the files, you run:</p>
<pre>svn update</pre>
<p>It bring your working copy up-to-date with the repository on the server.</p>
<p>That was it for Subersion at this time. I hope this article was of some help to you.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Install and Configure Git on Ubuntu</title>
		<link>https://wplancer.com/how-to-set-up-git-on-ubuntu/</link>
		
		<dc:creator><![CDATA[Baki Goxhaj]]></dc:creator>
		<pubDate>Thu, 30 Jan 2014 08:15:36 +0000</pubDate>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Version Control]]></category>
		<guid isPermaLink="false">https://wplancer.com/?p=1559</guid>

					<description><![CDATA[If you develop websites, like me, or write software of any kind, you should be using a version control system, and Git seems to lead the herd and I personally use it and I recommend it to anybody. This little tutorial is going to teach you how to set up Git on a computer running Ubuntu.]]></description>
										<content:encoded><![CDATA[<p>As they describe it:</p>
<blockquote><p>Git is a <a href="http://git-scm.com/about/free-and-open-source" rel="noopener">free and open source</a> distributed version control system designed to handle everything from small to very large projects with speed and efficiency.</p></blockquote>
<p>If you develop websites, like me, or write software of any kind, you should be using a version control system, and Git seems to lead the herd and I personally use it and I recommend it to anybody. This little tutorial is going to teach you how to set up Git on a computer running Ubuntu.<span id="more-1559"></span></p>
<h2>1. Installation</h2>
<p>To install git run the following command on <a title="Introduction to terminal" href="https://wplancer.com/a-beginners-guide-to-the-command-line/">terminal</a>:</p>
<pre>sudo apt-get install git</pre>
<h2>2. Configuration</h2>
<p>Git uses a name and email to label and identify your commits properly. Git your name, so that it can properly label the commits you make. Git saves your email address into the commits you make.</p>
<p>You configure your name by running this command on terminal:</p>
<pre>git config --global user.name "Y<em>our Name</em>"</pre>
<p>And your email by running this command:</p>
<pre>git config --global user.email "<em>your_email@example.com</em>"</pre>
<p>Please keep in mind that the quotation marks (&#8220;&#8221;) are needed.</p>
<p>And with this you are ready to <em>Git</em> to the real world. Yes, it is that easy.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
