<?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>Zulius &#187; how-to</title>
	<atom:link href="http://www.zulius.com/category/how-to/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zulius.com</link>
	<description>Advanced Application Development</description>
	<lastBuildDate>Fri, 30 Jul 2010 05:53:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Get yum to install a specific package version</title>
		<link>http://www.zulius.com/how-to/yum-install-specific-package-version/</link>
		<comments>http://www.zulius.com/how-to/yum-install-specific-package-version/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 05:53:53 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[yum]]></category>

		<guid isPermaLink="false">http://www.zulius.com/?p=710</guid>
		<description><![CDATA[Every once in a while you may need to install a specific version of a package on your system.  If you're using the yum package manager, it isn't blatantly obvious how to do this, even after pouring over the man pages.
So let's do this thing.
First, if you've already installed a newer version of the [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignleft" style="width: 160px"><img alt="yum fun" src="/img/blog/yumPackageVersion/titleImage.png" title="yum fun" width="150" height="110" /><p class="wp-caption-text">yum fun</p></div>
<p>Every once in a while you may need to install a specific version of a package on your system.  If you're using the yum package manager, it isn't blatantly obvious how to do this, even after pouring over the man pages.</p>
<p>So let's do this thing.</p>
<p>First, if you've already installed a newer version of the package, you'll have to downgrade it.  In that case, make sure you've got yum's downgrade plugin installed:</p>
<pre class="brush: plain;"># yum install yum-allowdowngrade</pre>
<p>Second, do you know exactly which package version you want to install?  If not, list the all available versions using the --showduplicates flag.  This example looks for available versions of the GD extension for PHP.</p>
<pre class="brush: plain;"># yum --showduplicates list php-gd

Available Packages
php-gd.i386                    5.2.3-3.el5s2                        testing
php-gd.i386                    5.2.6-2.el5s2                        testing
php-gd.i386                    5.2.9-2.el5.centos                   testing
php-gd.i386                    5.2.10-1.el5.centos                  testing
</pre>
<p>Yum is based on the RPM package manager, and it's package names are based on the <a href="http://en.wikipedia.org/wiki/RPM_Package_Manager#Package_label">RPM package label format</a>.  In the above example, the first column displays the package name and architecture in the format NAME.ARCHITECTURE.  The middle column displays the version and release info in the format VERSION-RELEASE.  Don't ask me why yum rearranges the RPM package label format.</p>
<p>Anyways, if you're downgrading, remove the previous package:</p>
<pre class="brush: plain;"># yum remove php-gd</pre>
<p>Now that you know which version to install, it's a matter of specifying the package name with the version.  Use the format NAME-VERSION.</p>
<pre class="brush: plain;"># yum install php-gd-5.2.6</pre>
<p>Or if you want to get even more specific, use NAME-VERSION-RELEASE (which might be easier to copy/paste since VERSION-RELEASE is the second column).</p>
<pre class="brush: plain;"># yum install php-gd-5.2.6-2.el5s2</pre>
<p>If you're downgrading, you may need to throw in the --allow-downgrade flag.</p>
<pre class="brush: plain;"># yum --allow-downgrade install php-gd-5.2.6</pre>
<p>And you should be good to go.  If you want to lock the version you installed to prevent any future updates, install the versionlock plugin.</p>
<pre class="brush: plain;"># yum install yum-versionlock</pre>
<p>Then lock it.</p>
<pre class="brush: plain;"># yum versionlock php-gd</pre>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=710&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/yum-install-specific-package-version/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Resolve Windows netbios names from Linux</title>
		<link>http://www.zulius.com/how-to/resolve-windows-netbios-names-from-linux/</link>
		<comments>http://www.zulius.com/how-to/resolve-windows-netbios-names-from-linux/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 11:59:57 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[netbios]]></category>
		<category><![CDATA[samba]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.zulius.com/?p=704</guid>
		<description><![CDATA[p>Platforms: any *nix distro
What You'll Need: Samba

In a heterogeneous LAN it is often useful to resolve network addresses by a computer's name (ie. netbios name).  This is especially true if the LAN does not have a DNS server so that host names can be used instead of IP addresses (which if dynamically assigned, could [...]]]></description>
			<content:encoded><![CDATA[<p><div class="wp-caption alignleft" style="width: 159px"><img alt="Ping a Windows box" src="/img/blog/resolveWindowsNetbiosTitleImate.png" title="Ping a Windows box" width="150" height="110" /><p class="wp-caption-text">Ping a Windows box</p></div>
<p><strong>Platforms: </strong><br />any *nix distro</p>
<p><strong>What You'll Need:</strong><br /> <a href="http://www.samba.org/">Samba</a></p>
<p>
In a heterogeneous LAN it is often useful to resolve network addresses by a computer's name (ie. <a href="http://en.wikipedia.org/wiki/NetBIOS">netbios</a> name).  This is especially true if the LAN does not have a DNS server so that host names can be used instead of IP addresses (which if dynamically assigned, could change often).</p>
<p>
To enable Windows netbios name resolution from a Linux computer, make sure that <a href="http://www.samba.org/">Samba</a> is installed (although the smb service does not need to be running).  The Samba suite includes <a href="http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/winbind.html">winbind</a>, which enables Windows host names to be resolved.</p>
<p>Then edit /etc/nsswitch.conf and change this line:</p>
<pre class="brush: plain;">hosts:      files dns</pre>
<p>to this:</p>
<pre class="brush: plain;">hosts:      files dns wins</pre>
<p>Then test by pinging the computer name of Windows machine on the LAN:</p>
<pre class="brush: plain;">$ ping windowsbox
PING windowsbox (192.168.0.100) 56(84) bytes of data.
64 bytes from 192.168.0.100: icmp_seq=1 ttl=128 time=0.117 ms
64 bytes from 192.168.0.100: icmp_seq=2 ttl=128 time=0.127 ms
64 bytes from 192.168.0.100: icmp_seq=3 ttl=128 time=0.127 ms
64 bytes from 192.168.0.100: icmp_seq=4 ttl=128 time=0.127 ms
64 bytes from 192.168.0.100: icmp_seq=5 ttl=128 time=0.128 ms</pre>
<p>This setting really comes in handy when mounting a shared folder of a dynamically IP'ed Windows box from Linux.  Instead of using the Windows' box IP address, just specify it's netbios name.  Example entry in /etc/fstab:</p>
<pre class="brush: plain;">
//windowsbox/my_share/ /mnt/my_mount_point/ cifs rw,username=xxx,password=xxx,domain=xxx 0 0
</pre>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=704&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/resolve-windows-netbios-names-from-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Send multidimensional arrays to PHP with jQuery and AJAX</title>
		<link>http://www.zulius.com/how-to/send-multidimensional-arrays-php-with-jquery-ajax/</link>
		<comments>http://www.zulius.com/how-to/send-multidimensional-arrays-php-with-jquery-ajax/#comments</comments>
		<pubDate>Sat, 26 Dec 2009 14:48:46 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.zulius.com/?p=656</guid>
		<description><![CDATA[AJAX communication between the client browser and web server is a handy method of transferring data without forcing the user to refresh the page.  Typically, the data sent to the server is a simple set of form fields or flags.  However, it is also possible to submit more complex structured data.  This [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignleft" style="width: 170px"><img alt="AJAX" src="/img/blog/assocArrayPhpJqueryAjax.png" title="AJAX" width="150" height="110" /><p class="wp-caption-text">javascript array</p></div>
<p><a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29">AJAX</a> communication between the client browser and web server is a handy method of transferring data without forcing the user to refresh the page.  Typically, the data sent to the server is a simple set of form fields or flags.  However, it is also possible to submit more complex structured data.  This tutorial will demonstrate 3 different methods used to pass multidimensional javascript arrays using <a href="http://jquery.com/">jQuery</a> and AJAX to a <a href="http://www.php.net/">PHP</a> web server.</p>
<h2>The Wrong Way</h2>
<p>My first instinct was that multidimensional JS arrays could be passed directly to jQuery's AJAX functions.  I expected that the array would be automatically preserved in the request, and show up in PHP's $_GET/$_POST variables.  The following example shows this doesn't work.</p>
<p>The code below attempts to post a JS associative array ("data", line 9) to the web server using jQuery's <a href="http://docs.jquery.com/Ajax/jQuery.ajax">$.ajax()</a> function.  The $.ajax() function is jQuery's lowest level AJAX function, but still provides a high level approach and lots of options.</p>
<pre class="brush: xml; first-line: 1; gutter: true;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; dir=&quot;ltr&quot; lang=&quot;en-US&quot;&gt;
    &lt;head profile=&quot;http://gmpg.org/xfn/11&quot;&gt;
        &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
        &lt;title&gt;jQuery AJAX arrays&lt;/title&gt;
        &lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;&gt;&lt;/script&gt;
        &lt;script type=&quot;text/javascript&quot;&gt;
                sendAjax = function(){
                    var data = {
                                  foo:  123,
                                  bar:  456,
                                  rows: [
                                          {
                                            column1 : 'hello',
                                            column2 : 'hola',
                                            column3 : 'bonjour',
                                          },
                                          {
                                            column1 : 'goodbye',
                                            column2 : 'hasta luego',
                                            column3 : 'au revoir',
                                          },
                                        ],
                                  test1:{
                                          test2: {
                                                   test3:  'baz'
                                                 }
                                        }
                                };

                    $.ajax({
                            type:           'post',
                            cache:          false,
                            url:            './ajax/',
                            data:           data
                           });
                }

        &lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;input type=&quot;button&quot; style=&quot;width: 130px; height: 60px&quot; value=&quot;send AJAX&quot; onclick=&quot;sendAjax();&quot; /&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>When the button is clicked, the following data shows up in PHP's $_POST variable:</p>
<pre class="brush: plain;">
Array
(
    [foo] =&gt; 123
    [bar] =&gt; 456
    [rows] =&gt; [object Object]
    [test1] =&gt; [object Object]
)
</pre>
<p>As shown, the first level of the array data is preserved (keys "foo" and "bar").  However, jQuery simply calls .toString() on the nested arrays at keys "rows" and "test1", and they get passed to PHP with the useless values "[object Object]".</p>
<h2>Method 1 - Form input arrays</h2>
<p>It's possible to name the keys of the JS array as HTML form input arrays (ie. named with square brackets) so that <a href="http://php.net/manual/en/language.variables.external.php">PHP decodes the array's key names as nested arrays</a>.  I don't recommend this method because it does not maintain the JS array's original structure in the Javascript.  However, it can be used if you just need to get the AJAX request working without using JSON.</p>
<p>
The original JS "data" array can be renamed/restructured as:
</p>
<pre class="brush: jscript;">
sendAjax = function(){
	var data = {
				  foo:  123,
				  bar:  456,
				  'rows[0][column1]':    'hello',
				  'rows[0][column2]':    'hola',
				  'rows[0][column3]':    'bonjour',
				  'rows[1][column1]':    'goodbye',
				  'rows[1][column2]':    'hasta luego',
				  'rows[1][column3]':    'au revoir',
				  'test1[test2][test3]': 'baz'
				};
	$.ajax({
			type:           'post',
			cache:          false,
			url:            './ajax/',
			data:           data
		   });
}
</pre>
<p>And the data is correctly received in PHP's $_POST variable:</p>
<pre class="brush: plain;">
Array
(
    [foo] =&gt; 123
    [bar] =&gt; 456
    [rows] =&gt; Array
        (
            [0] =&gt; Array
                (
                    [column1] =&gt; hello
                    [column2] =&gt; hola
                    [column3] =&gt; bonjour
                )

            [1] =&gt; Array
                (
                    [column1] =&gt; goodbye
                    [column2] =&gt; hasta luego
                    [column3] =&gt; au revoir
                )
        )

    [test1] =&gt; Array
        (
            [test2] =&gt; Array
                (
                    [test3] =&gt; baz
                )
        )
)
</pre>
<h2>Method 2 - JSON string parameter</h2>
<p>This method converts the JS array to a <a href="http://www.json.org/">JSON</a> string, and passes it as a POST or GET parameter, which can be manually decoded back into an array by PHP.  Modern browsers (Firefox 3, IE 8) now have a native JSON object that can be used to stringify JS arrays to JSON strings.  The following example uses the <a href="http://developer.yahoo.com/yui/json/">YUI JSON utility</a> to convert the JS array to a string ( <a href="http://www.json.org/json2.js">json2</a> is another populary lightweight utility for handling JSON).</p>
<pre class="brush: jscript;">
sendAjax = function(){
	var data = {
				  foo:  123,
				  bar:  456,
				  rows: [
						  {
							column1 : 'hello',
							column2 : 'hola',
							column3 : 'bonjour',
						  },
						  {
							column1 : 'goodbye',
							column2 : 'hasta luego',
							column3 : 'au revoir',
						  },
						],
				  test1:{
						  test2: {
								   test3:  'baz'
								 }
						}
				};
	data = YAHOO.lang.JSON.stringify(data);

	$.ajax({
			type:           'post',
			cache:          false,
			url:            './ajax/',
			data:           {myJson:  data}
		   });
}
</pre>
<p>On the PHP side, it's necessary to use <a href="http://us2.php.net/manual/en/function.json-decode.php">json_decode()</a> to convert the JSON $_POST parameter string (named "myJson") to an array:</p>
<pre class="brush: php;">
&lt;?php
$data = json_decode($_POST['myJson'], true);
print_r($data);
</pre>
<p>And the array is good to go:</p>
<pre class="brush: plain;">
Array
(
    [foo] =&gt; 123
    [bar] =&gt; 456
    [rows] =&gt; Array
        (
            [0] =&gt; Array
                (
                    [column1] =&gt; hello
                    [column2] =&gt; hola
                    [column3] =&gt; bonjour
                )

            [1] =&gt; Array
                (
                    [column1] =&gt; goodbye
                    [column2] =&gt; hasta luego
                    [column3] =&gt; au revoir
                )
        )

    [test1] =&gt; Array
        (
            [test2] =&gt; Array
                (
                    [test3] =&gt; baz
                )
        )
)
</pre>
<h2>Method 3 - JSON content-type</h2>
<p>My favorite method is to simply JSON stringify the JS array, and pass it as the AJAX request's body.  This requires that the content-type of the request be changed from the default "application/x-www-form-urlencoded" to "application/json", and that $.ajax()'s <a href="http://docs.jquery.com/Ajax/jQuery.ajax#options">processData</a> parameter be set to false so that the JSON data is not converted into a query string.  Also, the type of request must be POST, as the GET method does not support submitting data in the request body.</p>
<pre class="brush: jscript;">
sendAjax = function(){
	var data = {
				  foo:  123,
				  bar:  456,
				  rows: [
						  {
							column1 : 'hello',
							column2 : 'hola',
							column3 : 'bonjour',
						  },
						  {
							column1 : 'goodbye',
							column2 : 'hasta luego',
							column3 : 'au revoir',
						  },
						],
				  test1:{
						  test2: {
								   test3:  'baz'
								 }
						}
				};
	data = YAHOO.lang.JSON.stringify(data);

	$.ajax({
			type:           'post',
			cache:          false,
			url:            './ajax/',
			data:           data,
			processData:    false,
			contentType:   'application/json'
		   });
}
</pre>
<p>On the PHP side, it's necessary to manually read the JSON string directly from the request body using the <a href="http://php.net/manual/en/wrappers.php.php">php://input</a> stream.  The returned string can then be decoded into an array:</p>
<pre class="brush: php;">
&lt;?php
$data = file_get_contents('php://input');
$data = json_decode($data, true);
print_r($data);
</pre>
<p>Which gives us the array:</p>
<pre class="brush: plain;">
Array
(
    [foo] =&gt; 123
    [bar] =&gt; 456
    [rows] =&gt; Array
        (
            [0] =&gt; Array
                (
                    [column1] =&gt; hello
                    [column2] =&gt; hola
                    [column3] =&gt; bonjour
                )

            [1] =&gt; Array
                (
                    [column1] =&gt; goodbye
                    [column2] =&gt; hasta luego
                    [column3] =&gt; au revoir
                )
        )

    [test1] =&gt; Array
        (
            [test2] =&gt; Array
                (
                    [test3] =&gt; baz
                )
        )
)
</pre>
<p>Hopefully this tutorial has helped you get multidimensional array data passed to your webserver using AJAX.  If you know of another method, please submit it in the comments - thanks!</p>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=656&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/send-multidimensional-arrays-php-with-jquery-ajax/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Get numlock working with PuTTY and vim</title>
		<link>http://www.zulius.com/how-to/get-numlock-working-with-putty-and-vim/</link>
		<comments>http://www.zulius.com/how-to/get-numlock-working-with-putty-and-vim/#comments</comments>
		<pubDate>Sat, 19 Dec 2009 08:34:45 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[putty]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.zulius.com/?p=643</guid>
		<description><![CDATA[By default, your keyboard's numlock enabled number pad doesn't work well with console applications running on a PuTTY SSH connection.  The numpad's numbers seem to get mapped to inserting the characters "q" thru "y".  This is especially annoying when using vim.
To get numlock working, open PuTTY's configuration window, goto Terminal > Features.  [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignleft" style="width: 170px"><img alt="PuTTY" src="/img/blog/putty-vim-numpad/puttyTitleImage.jpg" title="PuTTY" width="150" height="110" /><p class="wp-caption-text">PuTTY</p></div>
<p>By default, your keyboard's numlock enabled number pad doesn't work well with console applications running on a PuTTY SSH connection.  The numpad's numbers seem to get mapped to inserting the characters "q" thru "y".  This is especially annoying when using vim.</p>
<p>To get numlock working, open PuTTY's configuration window, goto <b>Terminal > Features</b>.  Enable the "Disable application keypad mode" checkbox.</p>
<p>  If you want this setting to persist, make sure to select a saved session and click "Save".</p>
<p style="padding: 15px 0 0 0"><img class="alignnone" src="/img/blog/putty-vim-numpad/terminal-features.jpg" alt="Putty Configuration" /></p>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=643&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/get-numlock-working-with-putty-and-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: close browser connection and keep on executing</title>
		<link>http://www.zulius.com/how-to/close-browser-connection-continue-execution/</link>
		<comments>http://www.zulius.com/how-to/close-browser-connection-continue-execution/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 05:31:55 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.zulius.com/?p=543</guid>
		<description><![CDATA[Sometimes you need to execute a really long process after displaying a web page.  For example, you may need to evaluate the data a user submitted, and that operation may take a lot of time.  And since you're a thoughtful programmer, you don't want make the user stare at a blank page while [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignleft" style="width: 170px"><img alt="Close the browser's connection" src="/img/blog/php-close-browser-connection/titleImage.jpg" title="Close the browser's connection" width="150" height="110" /><p class="wp-caption-text">Close the browser's connection</p></div>
<p>Sometimes you need to execute a really long process after displaying a web page.  For example, you may need to evaluate the data a user submitted, and that operation may take a lot of time.  And since you're a thoughtful programmer, you don't want make the user stare at a blank page while they wait for the process to finish.</p>
<p>A good solution is to display a confirmation page and then close the browser's connection to the web server.  Closing the browser's connection will cause the browser to stop "spinning" and display a "Done" status.  The user can then feel assured that their part in the matter is over with, and can navigate elsewhere.  In the meantime, your PHP (or whatever language) continues executing on the server.  You could even get fancy with it, and use AJAX to display the script's execution progress to the user on the confirmation page.</p>
<p>The key to doing this are the two HTTP header fields:</p>
<pre style="margin: -5px 0 10px 0">
Connection: close
Content-Length: n (n = size of output in bytes )
</pre>
<p>The <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.10">"Connection: close"</a> header lets the browser know that it should not maintain a persistent connection.  The <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13">"Content-Length: "</a> header tells the browser how much data to expect.  Thus, it's necessary to supply the size of the output (in bytes) using "Content-Length: ".  Then the browser knows when it's downloaded everything and can terminate the connection.</p>
<h2>Example 1 - Basic Usage</h2>
<p>&nbsp;</p>
<pre class="brush: php; first-line: 1; gutter: true;">
&lt;?php
// buffer all upcoming output
ob_start();
echo &quot;Here's my awesome web page&quot;;

// get the size of the output
$size = ob_get_length();

// send headers to tell the browser to close the connection
header(&quot;Content-Length: $size&quot;);
header('Connection: close');

// flush all output
ob_end_flush();
ob_flush();
flush();

/******** background process starts here ********/
</pre>
<h2>Example 2 - embedded PHP with execution progress updates</h2>
<p><a target="_blank" href="/blog/scripts/examples/php/close-browser-connection/example1.php"class="demo">View the demo</a></p>
<p>This basic example executes some arbitrary time consuming code in the background, after the user clicks the submit button.  Notice that after clicking submit, the browser displays the web page and stops downloading.  Also, as a bonus, the execution progress of the script is displayed periodically using Prototype's PeriodicUpdater ajax calls.</p>
<ul>
<li><strong>Lines 02 - 19:</strong>&nbsp;&nbsp;AJAX handler that returns the progress of the background execution to the AJAX calls.  It's basically reading the contents of the progress file to the browser.</li>
<li><strong>Lines 22 - 35:</strong>&nbsp;&nbsp;Creates a uniquely named temporary file to track the background process's execution.  It also buffers all output (Line 034) so that we can calculate the size of all the content.  The size will be sent in the "Content-Length: " header.</li>
<li><strong>Lines 37 - 85:</strong>&nbsp;&nbsp;HTML content.  The javascript in Lines 68 - 80 setup a Prototype PeriodicUpdater.  It checks on the status of the background script every 1 second.</li>
<li><strong>Line 88:</strong>&nbsp;&nbsp;Calculates the size of the buffered output in bytes.</li>
<li><strong>Lines 90 -98:</strong>&nbsp;&nbsp;Sends the 2 necessary headers to the browser, and flushes all buffered output to the browser.</li>
<li><strong>Lines 100 - 115:</strong>&nbsp;&nbsp;This is where the background process should be executed.  In the example, some time consuming code is executed, and it's progress (ie. "Executing step n...") is written to a temporary progress file.</li>
</ul>
<p>Demo source code</p>
<pre class="brush: php; first-line: 1; gutter: true;">
&lt;?php
    // ajax updater handler
    if (isset($_POST['ajax']) &amp;&amp; $_POST['pidFile']){
        // clean input
        $pidFile = preg_replace('/[^\w\d]/', '', $_POST['pidFile']);
        $pidFile = &quot;../cache/$pidFile&quot;;

        if (! file_exists($pidFile)){
            header('HTTP/1.1 500 Internal Server Error');
            exit;
        }
        if(! $progress = file_get_contents($pidFile)){
            header('HTTP/1.1 500 Internal Server Error');
            exit;
        }

        echo nl2br($progress);
        exit;
    }

    // was form submitted?
    if(isset($_POST['submitted'])){
        // create a unique file to track script progress
        $pidFile = tempnam('../cache', '');

        // create the file for writing
        $fh = fopen($pidFile, 'wrx+');
        if (! $fh){
            print &quot;failed to create the file&quot;;
            exit;
        }

        // buffer all upcoming output
        ob_start();
    }
?&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
    &lt;head profile=&quot;http://gmpg.org/xfn/11&quot;&gt;
        &lt;title&gt;Zulius :: Close Browser Connection :: Example #1 Inline PHP&lt;/title&gt;
        &lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js&quot;&gt;&lt;/script&gt;
        &lt;style&gt;
            body{ text-align: center; margin: 20px auto; font-family: Arial, Helvetica, sans-serif;}
            div#progress{ min-height: 220px; margin: 10px auto}
        &lt;/style&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt;
        &lt;?php
        if(isset($_POST['submitted'])){
            echo 'background process started';
        }
        else{
            echo 'click to start background process';
        }
        ?&gt;
        &lt;/h1&gt;
        &lt;div id=&quot;progress&quot;&gt;
        &lt;/div&gt;
        &lt;form method=&quot;POST&quot;&gt;
            &lt;input type=&quot;submit&quot; name=&quot;submitted&quot; value=&quot;Go!&quot;&gt;
        &lt;/form&gt;
    &lt;/body&gt;
    &lt;?php
        if(isset($_POST['submitted'])){
        // show progress in browser
    ?&gt;
        &lt;script type=&quot;text/javascript&quot;&gt;
            updater = new Ajax.PeriodicalUpdater({success: 'progress'}, '&lt;?php echo $_SERVER['REQUEST_URI'] ?&gt;',
                                                { method: 'post',
                                                  frequency: 1,
                                                  decay: 1,
                                                  parameters: {
                                                               ajax: 1,
                                                               pidFile: '&lt;?php echo basename($pidFile) ?&gt;'
                                                             },
                                                  onFailure: function(){ this.stop(); }
                                                });
            setTimeout('updater.stop()', 15000);
        &lt;/script&gt;
    &lt;?php
        }
    ?&gt;
&lt;/html&gt;
&lt;?php
if(isset($_POST['submitted'])){
    // get the size of the output
    $contentLength = ob_get_length();

    // these headers tell the browser to close the connection
    // once all content has been transmitted
    header(&quot;Content-Length: $contentLength&quot;);
    header('Connection: close');

    // flush all output
    ob_end_flush();
    ob_flush();
    flush();

    /******** background process starts here ********/
    for($i=1;$i&lt;=10;$i++){
        if(fwrite($fh, &quot;Executing step $i...\n&quot;) == false){
            print &quot;failed to write to the file: &quot; . error_get_last();
            exit;
        }
        sleep(1);
    }

    fwrite($fh, &quot;Done!\n&quot;);
    sleep(2);

    fclose($fh);

    // delete the progress file
    unlink($pidFile);

}
</pre>
<h2>Example 3 - include embedded PHP file</h2>
<p>If you've separated the HTML from your main script, it's very easy to close the browser connection. Just capture the output from your include command, get the size of the content, and send the headers and content:</p>
<pre class="brush: php; first-line: 1; gutter: true;">
// capture output of include file in buffer
ob_start();
include '/path/to/your/content/file';

// get the size of the output
$contentLength = ob_get_length();

// these headers tell the browser to close the connection
// once all content has been transmitted
header(&quot;Content-Length: $contentLength&quot;);
header('Connection: close');

// flush all output
ob_end_flush();
ob_flush();
flush();

/******** background process code here ********/
</pre>
<h2>Background Process</h2>
<p>If your background process is vital and could take a lot of time, make sure to set these flags at the top of your script:</p</p>
<pre class="brush: php; first-line: 1; gutter: true;">
ignore_user_abort(true);
set_time_limit(0);
</pre>
<p><span style="font-family:  'Lucida Console', 'Courier New', Courier, monospace;">ignore_user_abort(true)</span> will prevent the script from halting if the user happens to push the browser's stop button before the connection is closed.  <span style="font-family:  'Lucida Console', 'Courier New', Courier, monospace;">set_time_limit(0)</span> will prevent your script from being terminated if it surpasses the <span style="font-family:  'Lucida Console', 'Courier New', Courier, monospace;">max_execution_time</span> set in php.ini.</p>
<p>Related post: <a href="/how-to/close-browser-connection-zend-framework">Close browser connection with Zend Framework</a></p>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=543&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/close-browser-connection-continue-execution/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Setup Postfix with a remote SMTP relay host</title>
		<link>http://www.zulius.com/how-to/set-up-postfix-with-a-remote-smtp-relay-host/</link>
		<comments>http://www.zulius.com/how-to/set-up-postfix-with-a-remote-smtp-relay-host/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 05:59:24 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[postfix]]></category>
		<category><![CDATA[smtp]]></category>

		<guid isPermaLink="false">http://www.zulius.com/wordpress/?p=3</guid>
		<description><![CDATA[p>Platforms: any Linux distro
What You'll Need: Postfix 2.2+ cyrus-sasl 2.1.19+ email account

A typical email scenario: you're a developer, and you've got a development Linux box at home.  You need to be able to send emails from your code or cron jobs, but you're too lazy to set up a full fledged email server on [...]]]></description>
			<content:encoded><![CDATA[<p><div class="wp-caption alignleft" style="width: 159px"><img alt="Postfix config" src="/img/blog/postfixTitleImage.jpg" title="Postfix config" width="149" height="110" /><p class="wp-caption-text">Postfix config</p></div>
<p><strong>Platforms: </strong><br />any Linux distro</p>
<p><strong>What You'll Need:</strong><br /> <a href="http://www.postfix.org">Postfix 2.2+</a><br /> <a href="http://freshmeat.net/projects/cyrussasl/">cyrus-sasl 2.1.19+</a><br /> email account
</p>
<p>A typical email scenario: you're a developer, and you've got a development Linux box at home.  You need to be able to send emails from your code or cron jobs, but you're too lazy to set up a full fledged email server on your LAN.  Or you just want to use your email account provided by your ISP.</p>
<p>Enter the Postfix.</p>
<p>Most Linux distros come with <a href="http://www.sendmail.org/">Sendmail</a> already installed, and is usually the default mail client used by the running services.  However, Postfix <a href="http://www.akadia.com/services/postfix_mta.html" target="_self">beats the crap out of Sendmail</a> and is a complete, seamless replacement.  Here's how I got it going on my CentOS box.</p>
<h2>Install</h2>
<p>Install Postfix and cyrus-sasl with your application manager of choice.  If you're compiling from source, be sure to make Postfix with the -DUSE_SASL_AUTH flag for SASL support and -DUSE_TLS for TLS support.</p>
<pre class="brush: plain;">$ yum install postfix cyrus-sasl</pre>
<p>Stop the sendmail service</p>
<pre class="brush: plain;">$ /etc/init.d/sendmail stop</pre>
<p>Remove sendmail from the startup runlevels</p>
<pre class="brush: plain;">$ chkconfig --del sendmail</pre>
<h2>Typical Setup</h2>
<p>Edit /etc/postfix/main.cf</p>
<pre class="brush: plain;"># Set this to your server's fully qualified domain name.
# If you don't have a internet domain name,
# use the default or your email addy's domain - it'll keep
# postfix from generating warnings all the time in the logs
mydomain = local.domain
myhostname = host.local.domain

# Set this to your email provider's smtp server.
# A lot of ISP's (ie. Cox) block the default port 25
# to prevent spamming.  So we'll use port 80
relayhost = yourisp.smtp.servername:80

smtpd_sasl_auth_enable = yes
smtpd_sasl_path = smtpd
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_type = cyrus
smtp_sasl_auth_enable = yes

# optional: necessary if email provider uses load balancing and
# forwards emails to another smtp server
# for delivery (ie: smtp.yahoo.com --&amp;gt; smtp.phx.1.yahoo.com)
smtp_cname_overrides_servername = no

# optional: necessary if email provider
# requires passwords sent in clear text
smtp_sasl_security_options = noanonymous</pre>
<p>There's roughly a 99.9% chance that your email provider's SMTP server requires authentication.  We need to set that up with the username and password given by your email provider.</p>
<p>Add the following line to /etc/postfix/sasl_passwd</p>
<pre class="brush: plain;"># The server info must exactly match the value
# for &quot;relayhost&quot; in /etc/postfix/main.cf
yourisp.smtp.servername:80 username:password</pre>
<p>Generate a postfix lookup table from the previous file</p>
<pre class="brush: plain;">$ postmap hash:/etc/postfix/sasl_passwd</pre>
<p>Test the lookup table, if all is good then the following will return the specified username:password</p>
<pre class="brush: plain;">$ postmap -q yourisp.smtp.servername:80 /etc/postfix/sasl_passwd</pre>
<p>Get rid of the clear text password file</p>
<pre class="brush: plain;">$ rm /etc/postfix/sasl_passwd</pre>
<p>Add postfix to be started at boot</p>
<pre class="brush: plain;">$ chkconfig --add postfix</pre>
<p>Fire up Postfix</p>
<pre class="brush: plain;">$ /etc/init.d/postfix start</pre>
<p>Test it out using sendmail from the command prompt</p>
<pre class="brush: plain;">$ sendmail email@example.com
Postfix is all up in dis hizzle.
.</pre>
<h2>Gmail Setup</h2>
<p>
If you're attempting to relay mail using Gmail, then it will be necessary to use TLS with Postfix.  You'll have to point Postfix at your server's trusted CA root certificate bundle, but luckily "<a href="http://www.felipe-alfaro.org/blog/2009/05/10/have-postfix-relay-e-mail-to-gmail/">...client-side certificates are not required when relaying mail to GMail</a>".
</p>
<p>First, double-check that Postfix was configured with SSL support (ie. ldd should return at least one line starting with libssl):</p>
<pre class="brush: plain;">$ whereis -b postfix
postfix: /usr/sbin/postfix /etc/postfix /usr/libexec/postfix
$ ldd /usr/sbin/postfix
...
libssl.so.6 =&gt; /lib/libssl.so.6 (0x00111000)
...
</pre>
<p>Now we need to find your server's CA root certificate bundle, which is typically distributed with openssl.  The bundle file is used by Postfix to verify Gmail's SSL certificate (signed by Thawte). On my CentOS server, this file was located at /etc/pki/tls/certs/ca-bundle.crt, but may be in a different location on your box (ie. /etc/ssl/certs).</p>
<pre class="brush: plain;">$ locate ca-bundle.crt
/etc/pki/tls/certs/ca-bundle.crt
</pre>
<p>Edit /etc/postfix/main.cf with the following values:</p>
<pre class="brush: plain;">
relayhost = smtp.gmail.com:587

# your FQDN, or default value below
mydomain = local.domain

# your local machine name, or default value below
myhostname = host.local.domain
myorigin = $myhostname

# SASL
smtpd_sasl_path = smtpd
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_type = cyrus
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous

# TLS
smtp_sasl_tls_security_options = noanonymous
smtp_use_tls  = yes
smtp_tls_CAfile = /path/to/your/ca-bundle.crt
smtp_sasl_tls_security_options = noanonymous
</pre>
<p>If you haven't already, add the following to /etc/postfix/sasl_passwd</p>
<pre class="brush: plain;"># The server info must exactly match the value
# for &quot;relayhost&quot; in /etc/postfix/main.cf
smtp.gmail.com:587 username:password</pre>
<p>Generate a postfix lookup table from the previous file</p>
<pre class="brush: plain;">$ postmap hash:/etc/postfix/sasl_passwd</pre>
<p>Get rid of the clear text password file</p>
<pre class="brush: plain;">$ rm /etc/postfix/sasl_passwd</pre>
<p>Restart postfix and send a test email</p>
<pre class="brush: plain;">$ postfix reload
$ sendmail email@example.com
Test relay thru Gmail
.</pre>
<h2>Troubleshooting</h2>
<p>Monitor postfix mail log in a separate session with the following command</p>
<pre class="brush: plain;">$ tail -f /var/log/maillog</pre>
<p>If the log is displaying the following error</p>
<pre class="brush: plain; toolbar: false;">(Authentication failed: cannot SASL authenticate to server ...: no mechanism available)</pre>
<p>then set this variable in /etc/postfix/main.cf</p>
<pre class="brush: plain;">smtp_sasl_security_options = noanonymous</pre>
<p>If the log is displaying this error</p>
<pre class="brush: plain; toolbar: false;">553 Sorry, that domain isn't in my list of allowed rcpthosts. (in reply to RCPT TO command)</pre>
<p>check your username and password in /etc/postfix/sasl_passwd.  Your user name is usually your full email address.  If you have to fix it, don't forget to use postmap to generate a new lookup table.</p>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=3&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/set-up-postfix-with-a-remote-smtp-relay-host/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Turn off TortoiseSVN sounds</title>
		<link>http://www.zulius.com/how-to/turn-off-tortoisesvn-sounds/</link>
		<comments>http://www.zulius.com/how-to/turn-off-tortoisesvn-sounds/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 19:00:14 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[tortoisesvn]]></category>

		<guid isPermaLink="false">http://www.zulius.com/?p=393</guid>
		<description><![CDATA[p>TortoiseSVN is an excellent Subersion client for Windows.  By default, TortoiseSVN makes noise when it encounters a warning or an error.  This almost made me crap a brick when TortoiseSVN failed on a commit and I forgot I had my speakers cranked to eleven.
TortoiseSVN does not have an internal setting to disable sounds, [...]]]></description>
			<content:encoded><![CDATA[<p><div class="wp-caption alignleft" style="width: 160px"><img alt="Noise on a commit failure" src="/img/blog/tortoiseSvnSound/error.jpg" title="Noise on a commit failure" width="150" height="110" /><p class="wp-caption-text">Noise on a commit failure</p></div>
<p><a href="http://tortoisesvn.tigris.org/">TortoiseSVN</a> is an excellent <a href="http://subversion.tigris.org/">Subersion</a> client for Windows.  By default, TortoiseSVN makes noise when it encounters a warning or an error.  This almost made me crap a brick when TortoiseSVN failed on a commit and I forgot I had my speakers cranked to eleven.</p>
<p>TortoiseSVN does not have an internal setting to disable sounds, so we'll have to manually disable it's noise in the Windows control panel:</p>
<ol>
<li>Right click anywhere, select TortoiseSVN > Settings > General Menu > Click "Configure" button next to System Sounds.  Or go to Start > Control Panel > Sounds and Audio Devices > Sounds Tab.
<p style="padding: 15px 0 0 0"><img class="alignnone" src="/img/blog/tortoiseSvnSound/tortoisesvn-settings.jpg" alt="TortoiseSVN settings" /></p>
</li>
<li>Look in the “Program Events” box for TortoiseSVN:
<p style="padding: 15px 0 0 0"><img class="alignnone" src="/img/blog/tortoiseSvnSound/sounds.jpg" alt="Sounds and Audio Device Properties" /></p>
</li>
<li>Click on each of TortoiseSVN's events, and select "(None)" from the <strong>Sounds</strong> dropdown.</li>
<li>Click OK.</li>
</ol>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=393&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/turn-off-tortoisesvn-sounds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Skip .svn directories when using grep</title>
		<link>http://www.zulius.com/how-to/grep-skip-svn-directories/</link>
		<comments>http://www.zulius.com/how-to/grep-skip-svn-directories/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 20:56:08 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[grep]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.zulius.com/?p=383</guid>
		<description><![CDATA[What You'll Need: grep 2.5.3+

I can't count how many times a day I use grep.  It is an indispensable tool for searching the contents of configuration files, data files, and source code.
One of the annoying side effects of grep is when searching a Subversion working copy recursively, all the hidden .svn directories also get [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignleft" style="width: 158px"><img alt="grep returns .svn metadata" src="/img/blog/title-image-grepSkipSvn.jpg" title="grep returns .svn metadata" width="148" height="110" /><p class="wp-caption-text">grep returns .svn metadata files</p></div>
<p><strong>What You'll Need:</strong><br /> <a href="http://www.gnu.org/software/grep/">grep 2.5.3+</a>
</p>
<p>I can't count how many times a day I use grep.  It is an indispensable tool for searching the contents of configuration files, data files, and source code.</p>
<p>One of the annoying side effects of grep is when searching a Subversion working copy recursively, all the hidden .svn directories also get searched.  This can yield a lot of false positive matches since these directories contain <a href="http://svn.collab.net/repos/svn/trunk/doc/user/svn-best-practices.html">"pristine copies of all version-controlled files"</a>.</p>
<p>If you've got grep 2.5.3 or higher, it's easy to ignore .svn directories with the "--exclude-dir" option:</p>
<pre class="brush: plain;">$ grep -r --exclude-dir='.svn' 'my search string' /some/directory</pre>
<p>But that's a lot to type in each time you want to search your source code.  To save keystrokes, try setting up an alias in your home directory's .bashrc file that utilizes the --exclude-dir option (for Mac, use your home directory's .profile file.).  I call mine <strong>devgrep</strong>:</p>
<pre class="brush: plain;">alias devgrep=&quot;grep --exclude-dir='.svn'&quot;</pre>
<p>After adding the alias, don't forget to source your .bashrc:</p>
<pre class="brush: plain;">$ source ~/.bashrc</pre>
<p>Now whenever you need to search a Subversion working copy recursively, use the new alias to skip .svn directories:</p>
<pre class="brush: plain;">$ devgrep -rin 'doctype' /var/www/html/templates
./foo.tpl:1:&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;
./bar.tpl:1:&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
./baz.phtml:1:&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Frameset//EN&quot; &quot;http://www.w3.org/TR/html4/frameset.dtd&quot;&gt;</pre>
<p>You can also exclude file types when grep'ing.  If you're a vim user, it can be helpful to skip .swp files in your alias:</p>
<pre class="brush: plain;">alias devgrep=&quot;grep --exclude-dir='.svn' --exclude='*.swp'&quot;</pre>
<p>Yet another workaround would be to use <a href="http://betterthangrep.com/">ack</a> - a Perl based, juiced up version of grep with a lot more features.</p>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=383&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/grep-skip-svn-directories/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fix Wordpress Editor on a Free GoDaddy Hosted Site</title>
		<link>http://www.zulius.com/how-to/fix-wordpress-editor-on-a-free-godaddy-hosted-site/</link>
		<comments>http://www.zulius.com/how-to/fix-wordpress-editor-on-a-free-godaddy-hosted-site/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 01:26:56 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[godaddy]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.zulius.com/blog/?p=107</guid>
		<description><![CDATA[Did you register a domain name with GoDaddy? Did you use the "free hosting credit" to setup your website's hosting?  Having problems getting the visual editor to work on your new Wordpress blog?  Then join the club - GoDaddy's infamous injected ads break the Javascript code that makes the TinyMCE visual editor work. [...]]]></description>
			<content:encoded><![CDATA[<p>Did you register a domain name with GoDaddy? Did you use the "free hosting credit" to setup your website's hosting?  Having problems getting the visual editor to work on your new Wordpress blog?  Then join the club - GoDaddy's infamous injected ads break the Javascript code that makes the TinyMCE visual editor work.  Luckily, it's fixable, and here's how.</p>
<h2>The Symptoms</h2>
<p>There are quite a few things that can cause the Wordpress WYSIWYG editor to break.  Using GoDaddy's free hosting service is certainly one of them.  A couple ways that you can tell you're experiencing the "GoDaddy" problem:</p>
<p style="padding-left: 30px;">1.  On the "Write Post" page, the post toolbar looks like this:</p>
<p style="padding-left: 0px;"><img class="alignnone" src="/img/blog/tinyMCE/brokenToolbar.png" alt="broken visual editor" /></p>
<p style="padding-left: 60px;">Instead of this:</p>
<p style="padding-left: 0px;"><img class="alignnone" src="/img/blog/tinyMCE/workingToolbar.png" alt="working visual editor" /></p>
<p style="padding-left: 30px;">2.  After browsing to the "Write Post" page in Firefox, open the error console by going to Tools &gt; Error Console.  This will is displayed:</p>
<p style="padding-left: 0px;"><img class="alignnone" src="/img/blog/tinyMCE/jsError.png" alt="" /></p>
<p style="padding-left: 30px;">
<p style="padding-left: 30px;">3.  Clicking the "HTML" button does nothing.</p>
<h2>The Fix</h2>
<p>Correcting this error involves a slight edit to one of the core Wordpress PHP files, namely "script-loader.php".  Please do so at your own risk.  This fix has been tested on Wordpress 2.6.3 with IE7 and Firefox 3.</p>
<h4 style="padding-left: 30px;">Step 1</h4>
<p style="padding-left: 60px;">Fire up your FTP client and FTP into the website you've got hosted on GoDaddy's server.  I used <a title="FireFTP" href="http://fireftp.mozdev.org/" target="_blank">FireFTP</a> in this example.  From here on, we'll assume that Wordpress is installed in the "/blog" directory.</p>
<h4 style="padding-left: 30px;">Step 2</h4>
<p style="padding-left: 60px;">We've got to get the TinyMCE Javascript code from the Javascript cache on the server.  Browse to the "/blog/wp-content/uploads/js_cache" directory in your FTP client.</p>
<p style="padding-left: 0px;"><img class="alignnone" src="/img/blog/tinyMCE/gzJsFile.png" alt="gzipped TinyMCE" /></p>
<p style="padding-left: 60px;">Look for a file named like this:</p>
<p style="padding-left: 90px;"><strong>tinymce_(a bunch of numbers and letters).gz</strong></p>
<p style="padding-left: 60px;">Download it.  Extract the contents of the file (you can use <a title="WinRar" href="http://www.rarlab.com/" target="_self">WinRar</a>, <a title="winzip" href="http://www.winzip.com/" target="_self">Winzip</a>, or <a title="7-Zip" href="http://www.7-zip.org/" target="_self">7-Zip</a>).  Rename the extracted javascript file from:</p>
<p style="padding-left: 90px;"><strong>tinymce_(a bunch of numbers and letters)</strong></p>
<p style="padding-left: 60px;">to:</p>
<p style="padding-left: 90px;"><strong>tinymce_fixed.js </strong></p>
<p style="padding-left: 0px;">Upload tinymce_fixed.js to the "/blog/wp-content/uploads/js_cache" directory on the GoDaddy server.</p>
<p style="padding-left: 0px;"><img class="alignnone" src="/img/blog/tinyMCE/fixedJsFile.png" alt="TinyMCE javascript" /></p>
<p style="padding-left: 60px;"><strong><i>Note:</i></strong> If the file "tinymce_(a bunch of numbers and letters)<strong>.gz</strong>" doesn't exist on the GoDaddy server, but a file named "tinymce_(a bunch of numbers and letters)<strong>.js</strong>" does, then rename the <strong>.js</strong> file  to "tinymce_fixed.js" without the quotes.  No downloading or extracting is required.</p>
<p style="padding-left: 60px;">If the js_cache directory doesn't exist, then either Wordpress doesn't have write permission to the wp-content folder, or you haven't opened the "Write Post" page yet.</p>
<h4 style="padding-left: 30px;">Step 3</h4>
<p style="padding-left: 60px;">In your FTP client, download the file "/blog/wp-includes/script-loader.php".</p>
<p style="padding-left: 0px;"><img class="alignnone" title="script-loader.php" src="/img/blog/tinyMCE/scriptLoader.png" alt="" /></p>
<p style="padding-left: 60px;">Open script-loader.php in your favorite editor, and comment out line 41.  Beneath that, insert the following new line of code:</p>
<div style="margin: 0 0 0 00px">
<pre class="brush: php; toolbar: false;">$scripts-&gt;add( 'tiny_mce', '/wp-content/uploads/js_cache/tinymce_fixed.js', array('editor_functions'), $mce_version );</pre>
</div>
<p style="padding-left: 60px;">The code should now look like this:</p>
<pre class="brush: php; first-line: 41; gutter: true; toolbar: false;">
//$scripts-&gt;add( 'tiny_mce', '/wp-includes/js/tinymce/tiny_mce_config.php', array('editor_functions'), $mce_version );
$scripts-&gt;add( 'tiny_mce', '/wp-content/uploads/js_cache/tinymce_fixed.js', array('editor_functions'), $mce_version );
</pre>
<p style="padding-left: 60px;">Upload and replace the script-loader.php file on the GoDaddy server.  You should then be good to go.  Also, make sure the "Use the visual editor when writing" option is enabled on your Wordpress profile page.</p>
<h2>Notes</h2>
<p style="padding-left: 30px;">Please be aware that if you upgrade Wordpress, you'll have to repeat this process to get the visual editor working again.  Same thing if you re-configure TinyMCE's settings in any way.</p>
<h2>Conclusion</h2>
<p style="padding-left: 30px;">GoDaddy's free hosting service places an ad at the top of your content using injected Javascript.  This seems to happen regardless of the response content-type headers when a PHP page is requested.</p>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=107&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/fix-wordpress-editor-on-a-free-godaddy-hosted-site/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Quickly indent multiple lines in vi/vim</title>
		<link>http://www.zulius.com/how-to/quickly-indent-multiple-lines-vi-vim/</link>
		<comments>http://www.zulius.com/how-to/quickly-indent-multiple-lines-vi-vim/#comments</comments>
		<pubDate>Wed, 12 Nov 2008 02:25:50 +0000</pubDate>
		<dc:creator>Tim White</dc:creator>
				<category><![CDATA[how-to]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.zulius.com/wordpress/?p=63</guid>
		<description><![CDATA[Indenting lines of programming code is essential for readability.  Indenting multiple lines at once is a feature that any useful code editing software should have.
As a programmer, I went far too long not knowing how to do this with vim (one of my favorite editors).  It's so easy, even Mike Tyson could do [...]]]></description>
			<content:encoded><![CDATA[<p>Indenting lines of programming code is essential for readability.  Indenting multiple lines at once is a feature that any useful code editing software should have.</p>
<p>As a programmer, I went far too long not knowing how to do this with <a href="http://www.vim.org/">vim</a> (one of my favorite editors).  It's so easy, even Mike Tyson could do it.  And he never learned to read.</p>
<ol style="bold">
<li>Enter VISUAL LINE mode by holding [SHIFT] and hitting the "v" key.</li>
<li>Use the arrow keys or "j" and "k" to select the lines you want to indent.</li>
<li>Hit the "&gt;" character (hold [SHIFT] and hit the "." key) to indent.  </li>
</ol>
<p>Then, you can repeat the indent using the "." key.  Likewise, you can type the "&lt;" character to outdent the selected lines.</p>
<img src="http://www.zulius.com/blog/?ak_action=api_record_view&id=63&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.zulius.com/how-to/quickly-indent-multiple-lines-vi-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
