<?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>Abban Dunne &#187; Notebook</title>
	<atom:link href="http://abandon.ie/category/notebook/feed/" rel="self" type="application/rss+xml" />
	<link>http://abandon.ie</link>
	<description>WordPress design &#38; development in Dublin, Ireland.</description>
	<lastBuildDate>Sat, 27 Apr 2013 07:04:19 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5</generator>
		<item>
		<title>Simple loading spinner for Backbonejs</title>
		<link>http://abandon.ie/simple-loading-spinner-for-backbonejs/</link>
		<comments>http://abandon.ie/simple-loading-spinner-for-backbonejs/#comments</comments>
		<pubDate>Tue, 27 Nov 2012 11:38:18 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=1052</guid>
		<description><![CDATA[Get your Backbone spinner on.]]></description>
				<content:encoded><![CDATA[<p>There ain&#8217;t much info on the internet on getting a loading spinner working with Backbone. It&#8217;s easy though! First go and create one over at <a href="http://fgnass.github.com/spin.js/">spin.js</a>, then copy the following code into your html, css and js:</p>
<h6>HTML (Right before the close body tag)</h6>
<pre class="brush: xml; title: ; notranslate">&lt;div id=&quot;loading&quot;&gt;&lt;/div&gt;</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">#loading{
    position:fixed;
    z-index:999;
    top:0;
    left:0;
    width:100%;
    height: 100%;
    background:rgba(0,0,0,0.3);
}</pre>
<h6>JS</h6>
<pre class="brush: jscript; title: ; notranslate">$(function(){
    $(&quot;#loading&quot;).spin({/* YOUR SPINNER OPTIONS */}).hide();
    $('#loading').ajaxStart(function(){ $(this).fadeIn(); });
    $('#loading').ajaxComplete(function(){ $(this).fadeOut(); });
});</pre>
<p>And bam, loading spinner that fires on all your backbone ajax calls. Of course this will work with any jQuery ajax framework too.</p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/simple-loading-spinner-for-backbonejs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Validate Facebook URLs &amp; Twitter Usernames with PHP Regular Expression</title>
		<link>http://abandon.ie/validate-facebook-urls-twitter-usernames-with-php-regular-expression/</link>
		<comments>http://abandon.ie/validate-facebook-urls-twitter-usernames-with-php-regular-expression/#comments</comments>
		<pubDate>Mon, 15 Oct 2012 13:58:08 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=1044</guid>
		<description><![CDATA[Validating Facebook URLs and Twitter usernames in your forms.]]></description>
				<content:encoded><![CDATA[<p>I was looking for a way to validate Facebook and Twitter user input and found relatively little information on it so I wrote these 2 little functions:</p>
<p><strong>Facebook URL Regex</strong></p>
<pre class="brush: php; title: ; notranslate">protected function valid_facebook_url($field){
    if(!preg_match('/^(http\:\/\/|https\:\/\/)?(?:www\.)?facebook\.com\/(?:(?:\w\.)*#!\/)?(?:pages\/)?(?:[\w\-\.]*\/)*([\w\-\.]*)/', $field)){
        return false;
    }
    return true;
}</pre>
<p><strong>Twitter Username Regex</strong></p>
<pre class="brush: php; title: ; notranslate">protected function valid_twitter_username($field){
    if(!preg_match('/^(\@)?[A-Za-z0-9_]+$/', $field)){
        return false;
    }
    return true;
}</pre>
<p>Hope this helps, I&#8217;m not 100% sure on the regex stuff so if you have any better methods let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/validate-facebook-urls-twitter-usernames-with-php-regular-expression/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exploring the WordPress Theme Customizer</title>
		<link>http://abandon.ie/exploring-wordpress-theme-customizer/</link>
		<comments>http://abandon.ie/exploring-wordpress-theme-customizer/#comments</comments>
		<pubDate>Thu, 21 Jun 2012 21:22:40 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=996</guid>
		<description><![CDATA[Introduction WordPress 3.4 has a fucking cool new feature on the themes page. Next to each theme theres a preview or a customize link that pops up a new overlay that lets the user live edit their themes. Adding extra theme options has been constant a pain the arse since I started developing themes all [...]]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>WordPress 3.4 has a fucking cool new feature on the themes page. Next to each theme theres a preview or a customize link that pops up a new overlay that lets the user live edit their themes. Adding extra theme options has been constant a pain the arse since I started developing themes all those few years ago. To make things easier for myself I even created a <a href="http://abandon.ie/abandon-options-plugin/">theme admin plugin</a>. I was never that happy with the plugin however and always too busy to make it work so the new theme customizer seems like a good timesaver for me and I decided to take a look at how to implement it.</p>
<p>The first thing I found was that as with all new WP features no-one has written any documentation for customising (Hey WP core developers, customise is spelled with a damn s!) it yet. All I could find was <a href="http://ottopress.com/2012/how-to-leverage-the-theme-customizer-in-your-own-themes/">this</a> description of the beta version. Also there doesn&#8217;t seem to be an API yet, it must be coming in a future release. However, there is an object called $wp_customize that you can add your custom theme settings to.</p>
<h2>Getting Started</h2>
<p>On loading up my starter theme in the preview I was suprised in seeing a half built menu already there. This is because WordPress is pulling the options for custom headers, backgrounds that you&#8217;ve added using the add_theme_support() function. It also pulls some core options like site title and displays them there.</p>
<h2>Custom Options</h2>
<p>Time for custom options. Going through the <a href="http://ottopress.com/2012/how-to-leverage-the-theme-customizer-in-your-own-themes/">blog post</a> I found I saw that the first thing you need to do is hook a function to the customize_register action like this:</p>
<pre class="brush: php; title: ; notranslate">function themename_customize_register($wp_customize){
    //STUFF IN HERE
}
add_action('customize_register', 'themename_customize_register');</pre>
<p>All your custom options go into there.</p>
<h2>Adding a Section</h2>
<p>This is simple enough as far as I can tell. You add one using the following:</p>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_section('themename_color_scheme', array(
    'title' =&gt; __('Color Scheme', 'themename'),
    'priority' =&gt; 120,
));</pre>
<p>So you pass through a unique slug and an array of arguments to the add_section method. I&#8217;m not 100% sure of all the arguments to pass through in the array, all I passed was the title and the priority. The priority is where you want the section to appear in the menu order. 1 is on the top and 120 seems to be the bottom.</p>
<h2>Adding options</h2>
<p>There are two methods you need to call to add an option. One to tell WordPress that an option exists and one to display whatever input box it needs. This is similar how the add_option()/update_option()/get_option() API works and it should be because it uses those functions to save the settings as far as I can tell/be bothered to check.</p>
<p>The first option type I&#8217;m going to show you is a standard text input box then I&#8217;ll breeze through the other types. You need to first call the add_setting() method to tell WP that you wish to save some new data. You do that like this:</p>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_setting('themename_theme_options[text_test]', array(
    'default'        =&gt; 'Arse!',
    'capability'     =&gt; 'edit_theme_options',
    'type'           =&gt; 'option',
));</pre>
<p>Similar to the add_section() method you pass through a slug and an array of args. You need to pass through a unique slug to this as the first parameter and it also allows you to pass the slug as an array index. The advantages of this is all your options are then available in the template in the one array keeping things nice and neat. The args I&#8217;ve found are:</p>
<ul>
<li>Default: The default value for the input.</li>
<li>Capability: This is the user role that is capable of editing these settings, I assume you would always set it to &#8216;edit_theme_options&#8217;.</li>
<li>Type: The way you want to store the data in WordPress, you can set it to &#8216;option&#8217; or &#8216;theme_mod&#8217;. I&#8217;ve always used option for saving theme preferences but if you prefer using theme mod then you can set it to save those here.</li>
</ul>
<p>Next you want to display your option in your custom section:</p>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_control('themename_text_test', array(
    'label'      =&gt; __('Text Test', 'themename'),
    'section'    =&gt; 'themename_color_scheme',
    'settings'   =&gt; 'themename_theme_options[text_test]',
));</pre>
<p>Again this works similarly to add_setting() and add_section() you pass a unique slug (Don&#8217;t really know why here as it&#8217;s only used as the list item css id) and an array of args. Some of the args are used for every input and some differ depending on the input element you want to display. The universal ones are:</p>
<ul>
<li>label: The form items label.</li>
<li>section: The section in which you want the form item to appear.</li>
<li>type: The type of form item you want. These are text, radio, checkbox and select. And are standard form elements. Textareas and HTML5 input types aren&#8217;t supported.</li>
<li>settings: This is the setting you want to use to save the values from the file input. You put in the unique slug of of the setting you want to use.</li>
<li>choices: These are only needed for radio buttons and dropdowns and contain the different options you want to display.</li>
</ul>
<p>You can also add options to the sections created by the WordPress core by passing their slug in the section arg. The ones I found are:</p>
<ul>
<li>Colors: colors</li>
<li>Header Image: header_image</li>
<li>Background Image: background_image</li>
<li>Static Front Page: static_front_page</li>
<li>Site Title &amp; Tagline: title_tagline</li>
<li>Navigation: nav</li>
</ul>
<h2>Standard Input Types</h2>
<p>These are just standard form items.</p>
<h3>Radio</h3>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_setting('themename_theme_options[color_scheme]', array(
    'default'        =&gt; 'value2',
    'capability'     =&gt; 'edit_theme_options',
    'type'           =&gt; 'option',
));

$wp_customize-&gt;add_control('themename_color_scheme', array(
    'label'      =&gt; __('Color Scheme', 'themename'),
    'section'    =&gt; 'themename_color_scheme',
    'settings'   =&gt; 'themename_theme_options[color_scheme]',
    'type'       =&gt; 'radio',
    'choices'    =&gt; array(
        'value1' =&gt; 'Choice 1',
        'value2' =&gt; 'Choice 2',
        'value3' =&gt; 'Choice 3',
    ),
));</pre>
<h3>Checkbox</h3>
<p>To be honest, I think I&#8217;m missing something here. It&#8217;s acting a bit wonkey. Maybe it&#8217;s broken?</p>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_setting('themename_theme_options[checkbox_test]', array(
    'capability' =&gt; 'edit_theme_options',
    'type'       =&gt; 'option',
));

$wp_customize-&gt;add_control('display_header_text', array(
    'settings' =&gt; 'themename_theme_options[checkbox_test]',
    'label'    =&gt; __('Display Header Text'),
    'section'  =&gt; 'themename_color_scheme',
    'type'     =&gt; 'checkbox',
));</pre>
<h3>Select Box</h3>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_setting('themename_theme_options[header_select]', array(
    'default'        =&gt; 'value2',
    'capability'     =&gt; 'edit_theme_options',
    'type'           =&gt; 'option',

));
$wp_customize-&gt;add_control( 'example_select_box', array(
    'settings' =&gt; 'themename_theme_options[header_select]',
    'label'   =&gt; 'Select Something:',
    'section' =&gt; 'themename_color_scheme',
    'type'    =&gt; 'select',
    'choices'    =&gt; array(
        'value1' =&gt; 'Choice 1',
        'value2' =&gt; 'Choice 2',
        'value3' =&gt; 'Choice 3',
    ),
));</pre>
<h3>Page Dropdown</h3>
<p>This displays a list of your pages. I guess you could allow the user to set pages for something custom. It&#8217;s weird that this is in there but not a category dropdown option.</p>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_setting('themename_theme_options[page_test]', array(
    'capability'     =&gt; 'edit_theme_options',
    'type'           =&gt; 'option',

));

$wp_customize-&gt;add_control('themename_page_test', array(
    'label'      =&gt; __('Page Test', 'themename'),
    'section'    =&gt; 'themename_color_scheme',
    'type'    =&gt; 'dropdown-pages',
    'settings'   =&gt; 'themename_theme_options[page_test]',
));</pre>
<p>You can hack in a category dropdown like this however:</p>
<pre class="brush: php; title: ; notranslate">$categories = get_categories();
$cats = array();
$i = 0;
foreach($categories as $category){
    if($i==0){
        $default = $category-&gt;slug;
        $i++;
    }
    $cats[$category-&gt;slug] = $category-&gt;name;
}

$wp_customize-&gt;add_setting('themename_theme_options[header_select]', array(
    'default'        =&gt; $default,
    'capability'     =&gt; 'edit_theme_options',
    'type'           =&gt; 'option',

));
$wp_customize-&gt;add_control( 'example_select_box', array(
    'settings' =&gt; 'themename_theme_options[header_select]',
    'label'   =&gt; 'Select Something:',
    'section' =&gt; 'themename_site_options',
    'type'    =&gt; 'select',
    'choices' =&gt; $cats,
));</pre>
<h2>Fancy Input Types</h2>
<p>These are custom input types and use javascript to work. They also all vary slightly from the others in that a new object needs to be created for each control.</p>
<h3>Image Upload</h3>
<p>Image upload is a file input type and allows users to upload an image. Handy for letting them set their logo.</p>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_setting('themename_theme_options[image_upload_test]', array(
    'default'           =&gt; 'image.jpg',
    'capability'        =&gt; 'edit_theme_options',
    'type'           =&gt; 'option',
));

$wp_customize-&gt;add_control( new WP_Customize_Image_Control($wp_customize, 'image_upload_test', array(
    'label'    =&gt; __('Image Upload Test', 'themename'),
    'section'  =&gt; 'themename_color_scheme',
    'settings' =&gt; 'themename_theme_options[image_upload_test]',
)));</pre>
<h3>File Upload</h3>
<p>Adds a custom file input. Good for allowing the end user to upload files I guess. Maybe a custom favicon would use this?</p>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_setting('themename_theme_options[upload_test]', array(
    'default'           =&gt; 'arse',
    'capability'        =&gt; 'edit_theme_options',
    'type'           =&gt; 'option',

));

$wp_customize-&gt;add_control( new WP_Customize_Upload_Control($wp_customize, 'upload_test', array(
    'label'    =&gt; __('Upload Test', 'themename'),
    'section'  =&gt; 'themename_color_scheme',
    'settings' =&gt; 'themename_theme_options[upload_test]',
)));</pre>
<h3>Color Picker</h3>
<p>Displays a colour picker. Gives the user the option to destroy your theme with their bad taste. This input seems to have a hex colour callback for sanitizing the value.</p>
<pre class="brush: php; title: ; notranslate">$wp_customize-&gt;add_setting('themename_theme_options[link_color]', array(
    'default'           =&gt; '000',
    'sanitize_callback' =&gt; 'sanitize_hex_color',
    'capability'        =&gt; 'edit_theme_options',
    'type'           =&gt; 'option',

));

$wp_customize-&gt;add_control( new WP_Customize_Color_Control($wp_customize, 'link_color', array(
    'label'    =&gt; __('Link Color', 'themename'),
    'section'  =&gt; 'themename_color_scheme',
    'settings' =&gt; 'themename_theme_options[link_color]',
)));</pre>
<h2>Displaying these options in your theme.</h2>
<p>Displaying this stuff is easy. Depending on if you set your setting_type() to option or theme_mod you can display it in the two following ways:</p>
<p>Option:</p>
<pre class="brush: php; title: ; notranslate">&lt;?php $options = get_option('themename_theme_options'); echo $options['input_name']; ?&gt;</pre>
<p>Theme Mod:</p>
<pre class="brush: php; title: ; notranslate">&lt;?php $options =  get_theme_mod('themename_theme_options'); echo $options['input_name']; ?&gt;</pre>
<h2>In Closing</h2>
<p>Thats as far as I got in a couple of hours research (fucking about), you can download a working gist of the examples that you can copy straight into your themes functions.php file below and have a fiddle with it yourself. Please feel free to correct whatever I have wrong up there as I made quite a few assumtions and have probably made a mistake or two.</p>
<p><a class="button" href="https://gist.github.com/2968549">Download the code</a></p>
<h2>Update 30th June: Javascript!</h2>
<p>Playing around with the customizer I just realized you have to use jQuery to do the live updates when a user changes options. It&#8217;s a bit hokey and I want to look into it a bit more. I&#8217;ll add that when I know it better.</p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/exploring-wordpress-theme-customizer/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Accessing The Piratebay and Other Blocked Sites with a Free Personal Proxy</title>
		<link>http://abandon.ie/accessing-the-piratebay-and-other-blocked-sites-with-a-free-personal-proxy/</link>
		<comments>http://abandon.ie/accessing-the-piratebay-and-other-blocked-sites-with-a-free-personal-proxy/#comments</comments>
		<pubDate>Thu, 03 May 2012 09:02:08 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=955</guid>
		<description><![CDATA[A post that details how to set up a free personal proxy in 5 minutes.]]></description>
				<content:encoded><![CDATA[<p>We&#8217;re in a critical place at the moment when it comes to online censorship. With ISPs and now (western) governments deciding what we can and cannot access I thought I&#8217;d write a small post on how to set up your own free personal proxy. A <a href="http://en.wikipedia.org/wiki/Proxy_server">proxy</a> is a tool that lets you route your traffic through a third party giving your browsing a little anonymity. Follow these steps to set up our own.</p>
<h2>Sign up for Github.</h2>
<p>Go to <a href="http://www.github.com">Github</a> and sign up for an account. This is pretty straightforward.</p>
<h2>Fork the Proxy.</h2>
<p>The proxy I&#8217;m using is a free open source one called <a href="http://www.glype.com/">Glype</a> I&#8217;ve modified it a little for ease of use. To get these files all you have to do is make sure you&#8217;re logged into Github and go to <a href="https://github.com/Abban/glype">here</a>. You&#8217;ll see a list of the files and some other stuff. What you need to do is get a copy of these onto your own Github account. To do this just hit the &#8216;Fork&#8217; button in the top right. This will copy the files from my Glype repository to yours. Take a note of the box with the repo URL in it, you&#8217;ll need that later.</p>
<div id="attachment_965" class="wp-caption alignnone" style="width: 752px"><img class="size-full wp-image-965 " title="github" src="http://abandon.ie/wp-content/uploads/2012/05/github1.jpg" alt="" width="742" height="335" /><p class="wp-caption-text">Fig.1 The blue box is the fork button. Remember the location of the green boxes for later.</p></div>
<h2>Sign up for Orchestra.</h2>
<p>Orchestra is a web hosting service that you can attach to a Github repository. Once it&#8217;s set up it will automatically take your files and deploy them as a live website. What you need to do is sign up for a free account which you can do <a href="http://my.orchestra.io/register">here</a>.</p>
<h2>Set up the Free App.</h2>
<p>Ok this is the most complicated bit, but its not so hard. Log in to Orchestra and go to &#8216;My Apps&#8217; Then click the &#8216;Deploy a Free App&#8217; button. This will give you a form to fill out. Here&#8217;s the fields explained:</p>
<ul>
<li><strong>Name:</strong> The name of your app. Put whatever you like in there, it has to be unique though.</li>
<li><strong>Repo URL:</strong> This is the location of the Github repository you set up in step 2. Look at the green box in Fig.1.</li>
<li><strong>Git Branch:</strong> Just leave this as master.</li>
<li><strong>Index File:</strong> This needs to be index.php</li>
<li><strong>SSH Key: </strong>In order for Orchestra to communicate with your Github repository an SSH key needs to be set up. Think of it as a password shared between the 2 services. You set it up like this:
<ol>
<li>Hit the generate SSH key button and it will make you a password.</li>
<li>Copy this and go to your Github repository and click &#8216;Admin&#8217;.</li>
<li>Click &#8216;Deploy Keys&#8217; and &#8216;Add Deply Key&#8217;.</li>
<li>Type Orchestra in the title and paste your generated key into the Key field.</li>
<li>Go back to Orchestra and hit &#8216;Launch App&#8217;.</li>
</ol>
</li>
</ul>
<p>And thats it, your free personal proxy will now be working at http://whatevername.orchestra.io</p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/accessing-the-piratebay-and-other-blocked-sites-with-a-free-personal-proxy/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WordPress Configuration for Multiple Environments</title>
		<link>http://abandon.ie/wordpress-configuration-for-multiple-environments/</link>
		<comments>http://abandon.ie/wordpress-configuration-for-multiple-environments/#comments</comments>
		<pubDate>Thu, 29 Mar 2012 18:03:46 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=926</guid>
		<description><![CDATA[A replacement for your WordPress wp-config file that lets you work in different environments.]]></description>
				<content:encoded><![CDATA[<p>No matter how small your business is, if you make websites you work in multiple environments. If you&#8217;re a freelancer working alone chances are that for each project you work on you have at least two environments, possibly three. One on your local machine, one for client previews, and maybe a further one for production.</p>
<p>If you work as part of a team it can get even more complicated. In my office we can have up to three people contributing on a job, each with their own local environment settings. Plus, depending on the needs of the client, there could be up to four server environments set up. Throw source control into the mix (and you really should be using source control) and you end up with a small headache just keeping track of whats going on.</p>
<p>In this post I&#8217;m documenting a method of working with WordPress and multiple environments but the same concepts can be applied across a range of other content management systems such as ExpressionEngine and Joomla or frameworks like CodeIgniter.</p>
<div id="attachment_932" class="wp-caption alignnone" style="width: 742px"><img class="size-full wp-image-932" title="source-diagram" src="http://abandon.ie/wp-content/uploads/2012/03/source-diagram1.png" alt="" width="732" height="464" /><p class="wp-caption-text">Fig 1. The different local and server environments.</p></div>
<h3>Overview of the different environments</h3>
<ol>
<li>The development environment is for testing settings on your server. It helps to test for problems which would be server specific. This is only for you or your team, the client never sees it.</li>
<li>The preview environment is for allowing your client to preview the current work in progress without having to give them access to the source code.</li>
<li>Staging is for testing before deployment to production and is hosted on the clients servers. You put the site up here towards the end of the project when you are happy letting them have access to the source code. If you have an ongoing retainer with the client you might ditch the preview environment and only use this.</li>
<li>Production is the live environment. The site is deployed here when it has been fully tested and is ready to be seen by the world.</li>
</ol>
<div class="sidebox" style="margin-top: -200px;">
<h3>The development cycle</h3>
<ol>
<li>The developer works on a feature in their local environment.</li>
<li>When the feature is ready, the developer commits it to the source control and deploys it to development server to test it.</li>
<li>When the feature is reviewed and tested it is deployed to preview server.</li>
<li>The client then previews and you go through a number of revisions.</li>
<li>When the client is happy they sign off and it is deployed to staging.</li>
<li>Then on launch day, the site is deployed to production.</li>
</ol>
</div>
<h3>The problem with this setup and WordPress</h3>
<p>The problem with the way WordPress is set up is that it has only one configuration file (wp-config.php) which allows you to specify your database details and a few other options for a single environment.</p>
<p>Say you&#8217;re finished working on a feature and you want to put it onto a preview site and allow the client to look at it. You create the webspace and deploy the latest revision from your source control. The wp-config file that gets uploaded to your preview server will still have the details for connecting to your local database meaning it won&#8217;t work. Changing these details to point to the servers database obviously means that then your local site won&#8217;t work. You can get around this by deploying, logging into the server through FTP and changing the settings manually but this isn&#8217;t really an ideal solution as theres still the chance it could be overwritten by accident through a future deployment.</p>
<h3>Configuration differences across environments</h3>
<ol>
<li>Database configuration.</li>
<li>Error reporting, it should be turned on on development servers and off on preview, staging and production.</li>
<li>Robots need to be blocked from development, preview and staging environments. Having Google display links to your work in progress is not just embarassing, duplicate content will hurt your clients SEO.</li>
<li>Keeping unauthorised people from accessing the development and preview environments.</li>
</ol>
<h2>The Solution</h2>
<p>Enter the solution, the multi-environment <a href="http://github.com/Abban/WordPress-Config-Bootstrap">wp-config bootstrap</a>. This is a custom file that replaces the wp-config file in your installation and helps you configure your different environments.</p>
<h3>How it works:</h3>
<p>This works by accessing the <code>$_SERVER['SERVER_NAME']</code> variable which gives us the server name. The environments each have a unique URL which gives them their own unique itentifier that will allow us differentiate between them, something similar to this:</p>
<ul>
<li><strong>Local</strong>: http://localhost/project (&#8220;localhost&#8221;)</li>
<li><strong>Development</strong>: http://dev.yoursite.com (&#8220;dev.&#8221;)</li>
<li><strong>Preview</strong>: http://preview.yoursite.com (&#8220;preview.&#8221;)</li>
<li><strong>Staging</strong>: http://stage.clientsite.com (&#8220;stage.&#8221;)</li>
<li><strong>Production</strong>: http://clientsite.com (none of the above, which is also unique!)</li>
</ul>
<p>Then we define a constant variable giving us an easy way to check the environment throughout the application. This all works like this:</p>
<pre class="brush: php; title: ; notranslate">

// Define Environments
$environments = array(
    'local' =&gt; '.local',
    'development' =&gt; '.dev',
    'staging' =&gt; 'stage.',
    'preview' =&gt; 'preview.',
);
// Get Server name
$server_name = $_SERVER['SERVER_NAME'];

foreach($environments AS $key =&gt; $env){
    if(strstr($server_name, $env)){
        define('ENVIRONMENT', $key);
        break;
    }
}

// If no environment is set default to production
if(!defined('ENVIRONMENT')) define('ENVIRONMENT', 'production');

</pre>
<h3>Adding your database connection details</h3>
<p>Now all we need to do to add the different database configuration details. I&#8217;m using a switch here but an if statement will work just as well.</p>
<pre class="brush: php; title: ; notranslate">

// Define different DB connection details depending on environment
switch(ENVIRONMENT){
    case 'local':
        define('DB_NAME', 'bootstrap');
        define('DB_USER', 'root');
        define('DB_PASSWORD', 'root');
        define('DB_HOST', 'localhost');
        define('WP_DEBUG', true);
        define('WP_SITEURL', 'http://bootstrap.local/');
        define('WP_HOME', 'http://bootstrap.local/');
        break;

    case 'development':

        define('DB_NAME', 'bootstrap');
        define('DB_USER', 'root');
        define('DB_PASSWORD', 'root');
        define('DB_HOST', 'localhost');
        define('WP_DEBUG', true);
        break;

    case 'staging':

        define('DB_NAME', 'database_name_here');
        define('DB_USER', 'username_here');
        define('DB_PASSWORD', 'password_here');
        define('DB_HOST', 'localhost');
        break;

    case 'preview':

        define('DB_NAME', 'database_name_here');
        define('DB_USER', 'username_here');
        define('DB_PASSWORD', 'password_here');
        define('DB_HOST', 'localhost');
        break;
}

// If database isn't defined then it will be defined here.
// Put the details for your production environment in here.
if(!defined('DB_NAME'))define('DB_NAME', 'database_name_here');
if(!defined('DB_USER')) define('DB_USER', 'username_here');
if(!defined('DB_PASSWORD')) define('DB_PASSWORD', 'password_here');
if(!defined('DB_HOST')) define('DB_HOST', 'localhost');
if(!defined('DB_CHARSET')) define('DB_CHARSET', 'utf8');
if(!defined('DB_COLLATE')) define('DB_COLLATE', '');

</pre>
<p>You should create different databases for each environment. However, if you want to use the same database for multiple ones you can define the <code>WP_SITEURL</code> and <code>WP_HOME constants</code> for each one inside the switch. This will hardcode the site URL meaning all your links will work.</p>
<p>Just be careful because if for example you&#8217;re using the same database for development and preview, any changes you make to content in development will then be reflected in the preview.</p>
<p>You could also use the same database and customise the table prefix for the environments which would effectively add multiple WordPress installations to the one database.</p>
<p>Lastly it can be set it up to turn on debugging automatically for the local and development environments and off for the others making sure you never accidentally leave it on on your production site.</p>
<h3>Other usage examples</h3>
<p>Now that we have the <code>ENVIRONMENT</code> variable set up we can add a few handy functions to the theme.</p>
<h4>is_production()</h4>
<p>A function to check if the current environment is production or not. Add this into your themes functions.php file:</p>
<pre class="brush: php; title: ; notranslate">
function is_production(){
    if(ENVIRONMENT == 'production'){
        return true;
    }else{
        return false;
    }
}
</pre>
<h4>Using Less or Sass</h4>
<p>If you like to use Less or Sass and only compile the CSS for the production you can add this snippet into your themes header:</p>
<pre class="brush: php; title: ; notranslate">
&lt;!--?php if(!is_production()): ?--&gt;
&lt;script type=&quot;text/javascript&quot;&gt;// &lt;![CDATA[
var less = { env: 'development' };
// ]]&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;?php bloginfo('template_directory'); ?&gt;/assets/js/libs/less-1.3.0.min.js&quot;&gt;&lt;/script&gt;
&lt;script charset=&quot;utf-8&quot; type=&quot;text/javascript&quot;&gt;// &lt;![CDATA[
 less.watch();
// ]]&gt;&lt;/script&gt;
&lt;!--?php else: ?--&gt;

&lt;!--?php endif; ?--&gt;
</pre>
<p>Just make sure you compile the CSS before deploying to production!</p>
<h4>Making the site accessible to only logged in users</h4>
<p>If you want to make sure only people who are logged in can see the site you can reirect all unlogged in requests to the WordPress login page. Handy for keeping clients from nosing around your development environment. Add this to functions.php:</p>
<pre class="brush: php; title: ; notranslate">
function password_protected(){
    if(!is_user_logged_in() &amp;&amp; (ENVIRONMENT == 'development' || ENVIRONMENT == 'staging')){
        wp_redirect(get_option('siteurl') .'/wp-login.php');
    }
}
add_action('template_redirect', 'password_protected');
</pre>
<h4>Adding a cookie check</h4>
<p>A simple way of adding a cookie check to your preview environment that only lets people with a preview cookie view it. The cookie is created by adding ?preview to the URL like this <code>http://preview.yoursite.com?preview</code></p>
<pre class="brush: php; title: ; notranslate">
function require_cookie(){
    if(isset($_GET['preview'])){
        setcookie('preview', 'yes', time()+36000, '/');
        header('Location: /');
        exit;
    }

    if(ENVIRONMENT == 'preview' &amp;&amp; (!isset($_COOKIE['preview']) || $_COOKIE['preview'] != &quot;yes&quot;)){
        wp_redirect( 'http://www.google.com', 302 );
        exit;
    }
}
add_action('init', 'require_cookie');
</pre>
<p>That will keep the general public out of the site while giving the client an easy way to preview it.</p>
<h4>Blocking robots</h4>
<p>As explained earlier, keeping crawlers out of your development, preview and staging sites is very important. You can make sure this is done automatically by adding the following snippet:</p>
<pre class="brush: php; title: ; notranslate">
function robots_access(){
    if(is_production() &amp;&amp; get_option('blog_public') == '0') update_option('blog_public', '1');
    if(!is_production() &amp;&amp; get_option('blog_public') == '1') update_option('blog_public', '0');
}
add_action('init', 'robots_access');
</pre>
<p>And there you have it, a nice professional way to manage your WordPress sites across your environments. This was inspired by <a href="http://twitter.com/micflan">Michael Flanagan&#8217;s</a> CodeIgniter setup and Leevi Grahams <a href="http://ee-garage.com/nsm-config-bootstrap">Config Bootstrap</a> for ExpressionEngine. You can download the wp-config file by clicking the link below and if you have any suggestions please leave a comment.</p>
<p><a class="button" href="http://github.com/Abban/WordPress-Config-Bootstrap">Download from Github</a></p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/wordpress-configuration-for-multiple-environments/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Clamnuts Concept</title>
		<link>http://abandon.ie/clamnuts-concept/</link>
		<comments>http://abandon.ie/clamnuts-concept/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 22:36:59 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=898</guid>
		<description><![CDATA[Concept design for Clamnuts a comic site run by Bob Byrne.]]></description>
				<content:encoded><![CDATA[<p>The last 6 months for me have just been pure web development. I&#8217;ve done next to no work in design and apart from reading blogs and stuff to keep up with the trends etc I think I&#8217;ve gotten a little rusty. So when one of my friends Bobby, who has been working on a redesign for his site <a href="http://clamnuts.com">Clamnuts</a> for some time sent me his current work in progress I decided to do a concept up for him. See it above. Also I&#8217;d like to say thanks to him for thanking me in his new book, which is awesome.</p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/clamnuts-concept/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Print a Jigoshop Cart Link with Price and Total Items</title>
		<link>http://abandon.ie/print-a-jigoshop-cart-link-with-price-and-total-items/</link>
		<comments>http://abandon.ie/print-a-jigoshop-cart-link-with-price-and-total-items/#comments</comments>
		<pubDate>Tue, 28 Feb 2012 23:06:10 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>
		<category><![CDATA[Jigoshop]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=835</guid>
		<description><![CDATA[A small code snippet to help you get better Jigoshop integration with your WordPress themes.]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s a simple function that you can add to your WordPress template to print out a Jigoshop cart amount, total price and link to the cart. It&#8217;s useful if you want a small consistent button somewhere in your theme, such as in the header, to link the user easily to the full cart page. To use it simply paste the following into your themes functions.php file:</p>
<pre class="brush: php; title: ; notranslate">
/**
 * abandon_cart_button
 *
 * Prints a Jigoshop cart button
 *
 * @param  string $prefix
 * @param  string $suffix
 *
 */
if(!function_exists('abandon_cart_button') &amp;&amp; class_exists('jigoshop_cart')){

    function abandon_cart_button($prefix = '', $suffix = ''){

        $cart_contents = jigoshop_cart::$cart_contents;

        $output = $prefix;

        if(!empty($cart_contents)){

            $cart_contents_count = jigoshop_cart::$cart_contents_count;

            $output .= $cart_contents_count;
            $output .= ($cart_contents_count == 1) ? ' Item - ' : ' Items - ';
            $output .= jigoshop_cart::get_cart_total();
            $output .= ' &lt;a class=&quot;button&quot; href=&quot;' .jigoshop_cart::get_cart_url() .'&quot;&gt;View Cart&lt;/a&gt;';

        }else{

            $output .= 'No Items';

        }

        $output .= $suffix;

        echo $output;
    }
}</pre>
<p>And then put the following wherever you want the button to appear:</p>
<pre class="brush: php; title: ; notranslate">&lt;?php if(function_exists('abandon_cart_button')) abandon_cart_button('&lt;div id=&quot;cart_button&quot;&gt;', '&lt;/div&gt;'); ?&gt;</pre>
<p>The function takes 2 optional parameters, one for content before the output and one for content after. Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/print-a-jigoshop-cart-link-with-price-and-total-items/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>YeSEO, a Quick Guide on Optimising Your WordPress Blog for SEO.</title>
		<link>http://abandon.ie/yeseo-a-quick-guide-on-optimising-your-wordpress-blog-for-seo/</link>
		<comments>http://abandon.ie/yeseo-a-quick-guide-on-optimising-your-wordpress-blog-for-seo/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 12:56:48 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Infographic]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=633</guid>
		<description><![CDATA[A basic guide to building your webpages and WordPress themes with SEO in mind.]]></description>
				<content:encoded><![CDATA[<p>SEO is a pretty important aspect to consider when designing a web page. In fact I consider it to be the <strong>most</strong> important aspect. For a beginner it can be hard to find accurate information on the best methods to optimise your webpages so here&#8217;s the basic SEO methods I use when designing and building a site. It&#8217;s geared towards WordPress as that&#8217;s my CMS of choice and search engines are very familiar with scraping it which makes it a good SEO headstart.</p>
<h2>SEO Ready Permalinks</h2>
<p>Permalinks are the URL structure of your site. Setting this up properly allows you to add keywords into your URL. You can do this in your WordPress admin by going to <em>Settings &gt; Permalinks</em>. There are a number of options but I suggest clicking &#8220;Custom Structure&#8221; and adding in:</p>
<pre class="brush: plain; title: ; notranslate">/%postname%/</pre>
<p>This will add your post titles into your URL and allow you to add SEO keywords to it. You can add other elements to it such as the date or the post id but make sure that your post name is in there too!</p>
<h2>Meta Title</h2>
<p>This is the most important tag on the whole page. Search engines weigh your keywords in here a whole lot more than any other element. There are some do&#8217;s and don&#8217;ts for this. Do build your theme in a way that will allow a user to use an SEO plugin to customise it for different posts. Don&#8217;t use a static description and even more important: <strong>Don&#8217;t make it the site name!</strong></p>
<h2>Meta Description</h2>
<p>Your meta description has no weight on your SEO. What it does is gives Google a short description of the page to go underneath the link to your post on their search page. This should not be static. You should either build it to be handled with an SEO plugin or leave it out. &#8220;Leave it out?!&#8221; you say, &#8220;You must be crazy!&#8221; But think of it like this, Google knows when it&#8217;s scraping a WordPress site. It gets a little grumpy when it sees a static description, but when it doesn&#8217;t exist it takes a look into the body copy and pulls the description out of that. So as long as you have your keywords in your copy Google will find a relevant bit of text to go into that spot.</p>
<h2>Meta Keywords</h2>
<p>These don&#8217;t really have any effect but the general consensus is that they can&#8217;t hurt. Some SEO &#8220;experts&#8221; will tell you that your competition will look at this to easily see what keywords you use but I think they&#8217;re just being paranoid.</p>
<h2>Logo</h2>
<p>A bit mistake that a lot of theme designers make with this is by putting the site name in a heading 1 tag and then use CSS Image replacement to add in the image of the logo. <strong>Do not do this. </strong>Heading 1 tags are for your page titles, if you put the site name/logo in a h1 then search engines see that as the most important heading on the page and every page has the exact same heading! Instead do it like this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;div id=&quot;logo&quot;&gt;SITE NAME&lt;/div&gt;
</pre>
<p>And use your CSS image replacement. This will give your page a more semantic structure. And actually here&#8217;s a quick note on:</p>
<h3>CSS Image Replacement</h3>
<p>This is totally acceptable if for example you want to use images for your navigation. What CSS replacement allows us to do is write up semantic html then make it look shinier by replacing the text with images in CSS. Search engines will then be able to read the text in the links and the users get some nice buttons. Just don&#8217;t use it to stuff your markup with keywords or you&#8217;ll get penalised. And so onto another quick note on:</p>
<h3>Navigation</h3>
<p>Search engines use your navigation to find out site structure so make it as easy for the robots to scrape as possible. Be careful about using Javascript on it as it might make it hard for them to read.</p>
<h2>Breadcrumbs</h2>
<p>When building a theme you should add in support for a breadcrumbs plugin. Breadcrumbs are crucial for the internal linking on your site and help both users and search engines know where they are in relation to the homepage. You should also make sure that your categories, tags and other taxonomies are well named and include your keywords.</p>
<h2>Page Heading</h2>
<p>Every page should have a h1 tag. This is the second most important element on your page after the meta title. You should put your main keywords in here. Don&#8217;t make them too long though, I try to keep mine to less than 10 words.</p>
<h2>Images</h2>
<p>I like to use a featured image for posts and pages in my WordPress themes then display them in a nice prominent way on the page. It is important when adding these images to put a caption with your keywords into the alt tag on the image. You can do this when uploading the picture in the admin panel. Some people like to load the alt tag with keywords but this is not good practice and will end up getting you penalised.</p>
<h2>Post Links</h2>
<p>When linking to posts you should use the post title as the text for the link. Just the text will do if the list is in the sidebar but if it is a WordPress archive page you should add the excerpt too so each post has a description. Also when linking to the full post you should put the post title as the first link. If you want to have a read more button add it as a second link to the post and place it after the excerpt.</p>
<h2>Sidebar</h2>
<p>Your sidebar should always come after the body content in you site code. If you need to place it to the left of the content use CSS floating to achieve it. Remember, search engines rate the content closes to the top of the source as the most important content on your pages.</p>
<h2>Content</h2>
<p>This is pretty self explanatory. If you are writing about a topic you need to make sure you use the right keywords the right amount in the post content. This is called keyword density. Basically it&#8217;s the percentage amount your chosen keywords are used compared to the rest of the content. It should be over 1% but I try and go for around 3-4%.</p>
<h2>Dynamic Content</h2>
<p>As mentioned before, be careful with dynamic content. Search engines aren&#8217;t able to crawl Flash or content loaded with javascript so this won&#8217;t be picked up. A huge mistake people make is having a flash site with no alternative for search engines. Plus the content won&#8217;t load on an iPhone!</p>
<h2>Semantic Code</h2>
<p>And lastly, you need to keep your code as clean as possible. A nice light semantic page with no errors will make it much easier for your content to get crawled and found.</p>
<blockquote><p>Clean code makes Google a happy, happy, hippopotamus.<br />
Abban Dunne &#8211; 2011.</p></blockquote>
<p>Lastly, lastly, remember these are only starting guidelines. SEO goes much deeper than just structuring your web pages correctly but this will give you a good start. If your WordPress theme follows these instructions and doesn&#8217;t make any of the obvious mistakes then I reckon you could definitely label it as an SEO ready theme. If you&#8217;re looking for a good plugin to handle some of the extra SEO functionality I highly recommend the <a href="http://yoast.com/wordpress/seo/">WordPress SEO Plugin</a> by <a href="http://yoast.com">Yoast</a>.</p>
<p>If you have any suggestions or updates please leave them in the comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/yeseo-a-quick-guide-on-optimising-your-wordpress-blog-for-seo/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Total Recall Minimal Movie Poster.</title>
		<link>http://abandon.ie/total-recall-minimal-movie-poster/</link>
		<comments>http://abandon.ie/total-recall-minimal-movie-poster/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 09:02:00 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>
		<category><![CDATA[Movie Poster]]></category>
		<category><![CDATA[Photoshop]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=617</guid>
		<description><![CDATA[Talking about the Total Reboot last night and I came up with a good minimal poster for it. ]]></description>
				<content:encoded><![CDATA[<p>For those of you that don&#8217;t know, Total Recall is being remade! Even better, Bryan Cranston (Walt from Breaking Bad) is gonna be in it! Talking about it last night the first topic that came up, and always comes up in TR discussions, was the three boob scene. Here&#8217;s a minimal poster.</p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/total-recall-minimal-movie-poster/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unhide Your Library Folder in OSX Lion</title>
		<link>http://abandon.ie/unhide-your-library-folder-in-osx-lion/</link>
		<comments>http://abandon.ie/unhide-your-library-folder-in-osx-lion/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 17:22:45 +0000</pubDate>
		<dc:creator>Abban</dc:creator>
				<category><![CDATA[Notebook]]></category>
		<category><![CDATA[Fonts]]></category>
		<category><![CDATA[OSX Lion]]></category>
		<category><![CDATA[Photoshop]]></category>

		<guid isPermaLink="false">http://abandon.ie/?p=613</guid>
		<description><![CDATA[Stupid Apple have decide we're not allowed to see the Library folder on our own laptops.]]></description>
				<content:encoded><![CDATA[<p>I just installed OSX Lion. One of the first things I noticed was different is that Apple have decided to hide the Library folder. This is a pretty stupid thing to do because anyone who uses Photoshop or wants to add fonts to their library will need it. You can however unhide it easily enough. All you need to do is type the following into Terminal:</p>
<pre class="brush: plain; title: ; notranslate">
chflags nohidden ~/Library
</pre>
<p>And bam, it&#8217;s back to normal.</p>
]]></content:encoded>
			<wfw:commentRss>http://abandon.ie/unhide-your-library-folder-in-osx-lion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
