<?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>FullFatCode</title>
	<atom:link href="http://www.fullfatcode.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fullfatcode.com</link>
	<description>The code blog of web developer James Carmichael</description>
	<lastBuildDate>Sun, 10 Apr 2011 00:07:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>jQuery Font Selector &#8211; version 2</title>
		<link>http://www.fullfatcode.com/2011/04/10/jquery-font-selector-version-2/</link>
		<comments>http://www.fullfatcode.com/2011/04/10/jquery-font-selector-version-2/#comments</comments>
		<pubDate>Sat, 09 Apr 2011 23:43:16 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[font]]></category>
		<category><![CDATA[picker]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=181</guid>
		<description><![CDATA[A guy called Rob just commented on the jQuery Font picker I posted a while back &#8211; and asked whether I could provide an example. Looking at the code I thought it was in need of a refresh, so have just rewritten it. You can see the jQuery font selector demo here. The plugin hasn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>A guy called Rob just commented on the jQuery Font picker I posted a while back &#8211; and asked whether I could provide an example. </p>
<p>Looking at the code I thought it was in need of a refresh, so have just rewritten it.  You can see the <a href="http://www.fullfatcode.com/examples/jqfontselector/">jQuery font selector demo</a> here. </p>
<p>The plugin hasn&#8217;t been extensively tested, but does seem to work OK in Chrome, Firefox and IE7 and 8.  Enjoy!</p>
<pre class="brush: jscript; title: ;">
/**
* Font selector plugin
* turns an ordinary input field into a list of web-safe fonts
* Usage: $('select').fontSelector();
*
* Author     : James Carmichael
* Website    : www.siteclick.co.uk
* License    : MIT
*/
jQuery.fn.fontSelector = function() {

  var fonts = new Array(
'Arial,Arial,Helvetica,sans-serif',
'Arial Black,Arial Black,Gadget,sans-serif',
'Comic Sans MS,Comic Sans MS,cursive',
'Courier New,Courier New,Courier,monospace',
'Georgia,Georgia,serif',
'Impact,Charcoal,sans-serif',
'Lucida Console,Monaco,monospace',
'Lucida Sans Unicode,Lucida Grande,sans-serif',
'Palatino Linotype,Book Antiqua,Palatino,serif',
'Tahoma,Geneva,sans-serif',
'Times New Roman,Times,serif',
'Trebuchet MS,Helvetica,sans-serif',
'Verdana,Geneva,sans-serif' );

  return this.each(function(){

    // Get input field
    var sel = this;

    // Add a ul to hold fonts
    var ul = $('&lt;ul class=&quot;fontselector&quot;&gt;&lt;/ul&gt;');
    $('body').prepend(ul);
    $(ul).hide();

    jQuery.each(fonts, function(i, item) {

      $(ul).append('&lt;li&gt;&lt;a href=&quot;#&quot; class=&quot;font_' + i + '&quot; style=&quot;font-family: ' + item + '&quot;&gt;' + item.split(',')[0] + '&lt;/a&gt;&lt;/li&gt;');

      // Prevent real select from working
      $(sel).focus(function(ev) {

        ev.preventDefault();

        // Show font list
        $(ul).show();

        // Position font list
        $(ul).css({ top:  $(sel).offset().top + $(sel).height() + 4,
                    left: $(sel).offset().left});

        // Blur field
        $(this).blur();
        return false;
      });

      $(ul).find('a').click(function() {
        var font = fonts[$(this).attr('class').split('_')[1]];
        $(sel).val(font);
        $(ul).hide();
        return false;
      });
    });

  });

}
</pre>
<p>And here is the required CSS:</p>
<pre class="brush: css; title: ;">
ul.fontselector {
  background: white;
  border: 1px solid #ccc;
  border-top: 0;
  font-size: 14px;
  float: left;
  list-style: none;
  margin: 0;
  padding:0;
  line-height: 1.2;
  z-index:    10;
  position:   absolute;
}
ul.fontselector li {
  margin:   0;
  padding:  0;
  list-style: none;
}
ul.fontselector a {
  display:    block;
  padding:    3px;
  color:      black;
  text-decoration: none;
}
ul.fontselector a:hover {
  background: #ddd;
  cursor:     pointer;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2011/04/10/jquery-font-selector-version-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VAT and SaaS Web Applications</title>
		<link>http://www.fullfatcode.com/2011/04/02/vat-and-saas-web-applications/</link>
		<comments>http://www.fullfatcode.com/2011/04/02/vat-and-saas-web-applications/#comments</comments>
		<pubDate>Sat, 02 Apr 2011 15:55:06 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=164</guid>
		<description><![CDATA[The UK VAT rules don&#8217;t exactly make it easy to create a software-as-a-service web application if you&#8217;re a UK based supplier who is VAT registered. The rules over whether VAT applies depends both on whether the service is for business use, where the customer is based, and where the service will be &#8216;enjoyed&#8217;. They do [...]]]></description>
			<content:encoded><![CDATA[<p>The UK VAT rules don&#8217;t exactly make it easy to create a software-as-a-service web application if you&#8217;re a UK based supplier who is VAT registered.  The rules over whether VAT applies depends both on whether the service is for business use, where the customer is based, and where the service will be &#8216;enjoyed&#8217;.</p>
<p>They do publish <a href="http://customs.hmrc.gov.uk/channelsPortalWebApp/downloadFile?contentID=HMCE_CL_001727">this flowchart</a> which makes it slightly easier to tell what&#8217;s what.</p>
<p>I set about trying to code up the logic in this PDF &#8211; if anyone is setting up a web application in the UK using PHP please feel free to use or adapt the code below.</p>
<p>There are some unit tests at the bottom which should ensure the logic matches that on the HMRC&#8217;s flowchart.</p>
<pre class="brush: php; title: ;">
&lt;?php

function is_eu($sLocation) {
  $sLocation = strtolower($sLocation);
  switch($sLocation) {
    case 'uk':
      return true;

    case 'eu':
      return true;

    case 'non-eu':
      return false;
  }
  trigger_error('Unknown location &quot;' . $sLocation . '&quot;', E_USER_ERROR);
}

function vat_applies($bBusiness = true, $sLocation = 'UK', $sEnjoyed = 'UK') {
  $sLocation = strtolower($sLocation);
  $sEnjoyed  = strtolower($sEnjoyed);

  // Validate input
  $aOptions  = array('uk', 'eu', 'non-eu');
  if(!in_array($sLocation, $aOptions)) {
    trigger_error('Customer location &quot;' . $sLocation . '&quot; invalid (must be uk, eu, non-eu)',
E_USER_ERROR);
  }
  if(!in_array($sEnjoyed, $aOptions)) {
    trigger_error('Services enjoyed in &quot;' . $sEnjoyed . '&quot; invalid (must be uk, eu, non-eu)',
E_USER_ERROR);
  }
  if(!is_bool($bBusiness)) {
    trigger_error('Business use must be boolean (true or false)', E_USER_ERROR);
  }

  // Customer in EU
  if(is_eu($sLocation)) {

    // Customer in UK
    if($sLocation == 'uk') {

      // Business purposes
      if($bBusiness) {

        // Service enjoyed outside EU
        if(!is_eu($sEnjoyed)) {
          return false;
        }
        // Service enjoyed inside EU
        else {
          return true;
        }

      }
      // Non-business purposes
      else {
        return true;
      }

    }
    // Customer not in UK
    else {
      // Business purposes
      if($bBusiness) {
        return false;
      }
      // Non-business purposes
      else {
        return true;
      }
    }

  }
  // Customer is not in EU
  else {
    // Business use
    if($bBusiness) {

      // Enjoyed in EU
      if(is_eu($sEnjoyed)) {

        // Enjoyed in UK
        if($sEnjoyed == 'uk') {
          return true;
        }
        else {
          return false;
        }
      }
      // Not enjoyed in EU
      else {
        return false;
      }
    }
    else {
      return false;
    }
  }
}

/**
 * Unit testing
 */
 /*
function assert_true($b) {
  echo '&lt;li&gt;' . ($b === true ? 'passed' : 'failed');
}
function assert_false($b) {
  echo '&lt;li&gt;' . ($b === false ? 'passed' : 'failed');
}

// Customer in UK - business
assert_true(vat_applies(true, 'uk', 'uk'));
assert_true(vat_applies(true, 'uk', 'eu'));
assert_false(vat_applies(true, 'uk', 'non-eu'));

// Customer in UK - non-business
assert_true(vat_applies(false, 'uk', 'uk'));
assert_true(vat_applies(false, 'uk', 'eu'));
assert_true(vat_applies(false, 'uk', 'non-eu'));

// Customer in EU
assert_false(vat_applies(true, 'eu', 'non-eu'));
assert_true(vat_applies(false, 'eu', 'non-eu'));

// Customer outside EU
assert_false(vat_applies(false, 'non-eu', 'non-eu'));
assert_false(vat_applies(true, 'non-eu', 'non-eu'));
assert_true(vat_applies(true, 'non-eu', 'uk'));
assert_false(vat_applies(true, 'non-eu', 'eu'));
assert_false(vat_applies(true, 'non-eu', 'non-eu'));
*/
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2011/04/02/vat-and-saas-web-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Doctrine PHP Merge Function</title>
		<link>http://www.fullfatcode.com/2009/12/12/doctrine-php-merge-function/</link>
		<comments>http://www.fullfatcode.com/2009/12/12/doctrine-php-merge-function/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 00:50:58 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[synchronizeWithArray]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=141</guid>
		<description><![CDATA[If you&#8217;ve tried Doctrine PHP, you might get pretty frustrated when using the $Record::synchronizeWithArray() function. Why? $data = array('name' =&#62; 'jimbob'); $User-&#62;Doctrine::getTable('User')-&#62;find(1); $User-&#62;synchronizeWithArray($data); $User-&#62;save(); If you try this code you will find that the synchronizeWithArray() function deletes everything except the &#8216;name&#8217; field in the record. I think the name &#8216;synchronize&#8217; is slightly confusing here, as [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve tried Doctrine PHP, you might get pretty frustrated when using the $Record::synchronizeWithArray() function.  Why?</p>
<pre class="brush: php; title: ;">

$data = array('name' =&gt; 'jimbob');

$User-&gt;Doctrine::getTable('User')-&gt;find(1);

$User-&gt;synchronizeWithArray($data);

$User-&gt;save();
</pre>
<p>If you try this code you will find that the synchronizeWithArray() function deletes everything except the &#8216;name&#8217; field in the record.  I think the name &#8216;synchronize&#8217; is slightly confusing here, as what it really means is &#8220;delete everything except what I&#8217;m explicitly telling you right now&#8221;.</p>
<p>A bit of digging in the API reference turned up a nice function called merge().</p>
<pre class="brush: php; title: ;">

$data = array('name' =&gt; 'jimbob');

$User-&gt;Doctrine::getTable('User')-&gt;find(1);

$User-&gt;merge($data);

$User-&gt;save();
</pre>
<p>You will find that all the fields except &#8216;name&#8217; are untouched.  Lovely job.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2009/12/12/doctrine-php-merge-function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPMailer and HTML email</title>
		<link>http://www.fullfatcode.com/2009/11/25/phpmailer-and-html-email/</link>
		<comments>http://www.fullfatcode.com/2009/11/25/phpmailer-and-html-email/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 13:34:24 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[Html]]></category>
		<category><![CDATA[PHPMailer]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=130</guid>
		<description><![CDATA[If you haven&#8217;t already tried it, the PHPMailer class is an excellent way of sending email using PHP. It makes all those dreaded email tasks (multiple message parts, encoding, attachments etc.) really nice and easy. Today however I came across a problem sending HTML formatted email &#8211; only occuring when sending via the PHP mail() [...]]]></description>
			<content:encoded><![CDATA[<p>If you haven&#8217;t already tried it, the PHPMailer class is an excellent way of sending email using PHP.  It makes all those dreaded email tasks (multiple message parts, encoding, attachments etc.) really nice and easy.</p>
<p>Today however I came across a problem sending HTML formatted email &#8211; only occuring when sending via the PHP mail() transport rather than SMTP.</p>
<p>I eventually traced it to a large block of HTML which formed part of the formatted email.  This was generated by a WYSIWYG editor and had no newline characters, and so was too long to handle for the mail() function (the SMTP transport was able to resolve the issue, but I didn&#8217;t want to use SMTP for this application).</p>
<p>The $mail-&gt;WordWrap parameter didn&#8217;t seem to help either.</p>
<p>So I rustled up a quick little function to split the HTML at opening tag boundaries, which solved the problem while keeping the code tidy &#8211; here it is:</p>
<pre class="brush: php; title: ;">
/**
* Function to wrap HTML, but only at opening tag boundaries
* @param    $s            the HTML string to wrap
* @param    $chars  the number of chararacters to allow per line
* @return $s            the modified HTML
*/
function htmlWrap($s, $chars = 40) {
$aChunks = explode('&lt;', $s);

$sLine     = '';
$aLines  = array();

foreach($aChunks as $i =&gt; $sChunk) {
$sLine .= ($i == 0 ? '' : '&lt;') . $sChunk;

// Check if line length too long
if(strlen($sLine) + strlen(@$aChunks[$i+1]) + 1 &gt;= $chars) {
$aLines[]    =    $sLine;
$sLine        = '';
}
}

return implode(&quot;\n&quot;, $aLines);
}
</pre>
<p>You can use this as so:</p>
<pre class="brush: php; title: ;">
$Mail             = new PHPMailer();
$Mail-&gt;MsgHTML(htmlWrap('Your HTML email message here...'));
...
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2009/11/25/phpmailer-and-html-email/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Choosing a CMS in 10 Steps</title>
		<link>http://www.fullfatcode.com/2009/09/03/choosing-a-cms-in-10-steps/</link>
		<comments>http://www.fullfatcode.com/2009/09/03/choosing-a-cms-in-10-steps/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 09:20:44 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[CMS]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=118</guid>
		<description><![CDATA[Picture this: you have a great website contract, a stunning design, and everything is ready to roll. Except for one little problem: which content management system (CMS) should be used? There&#8217;s no real right or wrong answer to this question, but it can certainly cause a lot of grief if you&#8217;re battling the technology rather [...]]]></description>
			<content:encoded><![CDATA[<p>Picture this:  you have a great website contract, a stunning design, and everything is ready to roll.  Except for one little problem:  which content management system (CMS) should be used?</p>
<p>There&#8217;s no real right or wrong answer to this question, but it can certainly cause a lot of grief if you&#8217;re battling the technology rather than being assisted by it.  So here&#8217;s a couple of handy pointers to help with the decision:</p>
<p><strong>1. Blog or CMS?</strong></p>
<p>If the website is primarily going to handle &#8216;posts&#8217; &#8211; journal entries spread out in time &#8211; then a blog is more appropriate.  If on the other hand you need to organise a quantity of more structured articles, such as sales literature or support documents, a CMS is going to be your best bet.</p>
<p>There&#8217;s actually a fair amount of crossover between blogs and CMS systems these days, but you may as well start out with a tool that&#8217;s specialised for the task at hand.</p>
<p><a href="http://www.wordpress.org">WordPress </a>is becoming fairly ubiquitous for blogging, with a vast range of third-party themes and plugins available.</p>
<p><strong>2. Self-hosted or cloud-hosted</strong></p>
<p>&#8216;CMS as a service&#8217;, where the software is pre-installed and ready to use, is becoming increasingly popular.  Available at a whole range of price points, from web-builder type software with pre-designed templates (such as <a href="http://www.jimdo.com/">Jimdo</a>) right up to fully fledged business solutions.  Our own <a href="http://www.creationcentre.co.uk">CreationCentre CMS</a> falls within the cloud-hosted CMS category, and can be implemented very rapidly.  If you are using a cloud-hosted solution, what data backup procedures are in place?</p>
<p>For blogging, there are popular pre-installed choices such as <a href="http://www.wordpress.com">WordPress.com</a> and <a href="http://www.blogger.com">Blogger.com</a>.</p>
<p>If you are planning to write your own modules, in a language such as PHP or ASP.NET, or require bespoke database interaction, you&#8217;re probably going to require a self-hosted solution.  Popular solutions here include <a href="http://www.joomla.org/">Joomla</a>, <a href="http://drupal.com/">Drupal</a>, and <a href="http://expressionengine.com/">Expression Engine</a>.</p>
<p><strong>3. Programming Language</strong></p>
<p>For cloud-hosted solutions this isn&#8217;t an issue, but if you&#8217;re installing it yourself the language the CMS is written in (as well as the database that persists it) is going to be an important factor &#8211; especially if the client already has a server they wish to use.</p>
<p>Popular choices here include PHP, ASP.NET, Java, and Ruby is spreading quickly too.</p>
<p><strong>4. Built-In Features</strong></p>
<p>You might find it useful at this stage to draw a spider diagram with &#8216;Website&#8217; in the middle, and broad technical requirements on each of the spokes.  Keep going out until you&#8217;ve exhausted every possible situation.</p>
<p>Which CMS seems to fit the bill most closely?  The closer the match, the better.</p>
<p>Here&#8217;s a couple of the more obvious features:</p>
<ul>
<li>Allow for easy management of articles, and the publication of new ones</li>
<li>Upload and manage images and files</li>
<li>Customisation of templates (whether in vanilla HTML or a scripting language such as PHP)</li>
<li>Blogging or news-posting</li>
<li>RSS feeds</li>
<li>Embedding of custom HTML such as YouTube video or Google Maps</li>
<li>Contact forms</li>
<li>Galleries</li>
<li>Website login accounts, with the ability to set user-only content</li>
<li>E-commerce facilities</li>
<li>Forum</li>
<li>SEO tools such as meta and title tag control</li>
<li>Permissions &#8211; the ability to allow only certain users to control certain articles or features</li>
<li>Workflow tools &#8211; allowing a logical flow to the creation and approval of content</li>
<li>Document lifecycle tools &#8211; keeping a record of all revisions made to a particular article</li>
</ul>
<p><strong>5. Page-centric or content-centric</strong></p>
<p>Some CMSs have the &#8216;page&#8217; as the unit of content.  In others, content exists in units independent of pages, with one or more content items being displayed on a particular page.</p>
<p>The former method is definitely easier to grasp, and works well if the website is relatively small or the end user is not technical.  The latter is more powerful, and can support &#8216;content-reuse&#8217;, where blocks of content can be reused on other pages or even websites in multi-site implementations.</p>
<p><strong>6. Usability</strong></p>
<p>Who is going to be using the CMS on a day-to-day basis?  If they&#8217;re not particularly technical then this is a crucial point, otherwise you will be inundated with support requests.</p>
<p>For example, not all CMS&#8217;s allow for WYSIWYG editing, meaning the user is going to have to learn either basic HTML or a similar in order to format their content.  Are they capable?  How much training will they require, and who&#8217;s going to perform that training?</p>
<p>Choose a CMS which is appropriate for the end-user.</p>
<p><strong>7.  Support and Documentation</strong></p>
<p>This is a crucial one too &#8211; how much support and documentation are available to you as a developer while you build the website?  You don&#8217;t want to be left high and dry with important deadlines to meet.</p>
<p>What are the ongoing support costs from the vendor, and does this cover software upgrades?</p>
<p><strong>8. Compatibility</strong></p>
<p>Most CMS systems run in the browser &#8211; it&#8217;s worth checking what operating system the end-user has, and what browser they have installed.  Unfortunately some corporate users may not have administrative permission to install the browser you wish they had!</p>
<p>Does the CMS need to interface with any other business software &#8211; the most obvious being Customer Relationship Management (CRM) software?  It&#8217;s definitely a bonus if after filling in an online contact form, the customer&#8217;s information is seamlessly imported into their CRM profile.</p>
<p>Thanks to XML and web services, the CMS can work as part of a larger whole rather than being a single silo of information.</p>
<p><strong>9. Accessibility</strong></p>
<p>It&#8217;s a legal requirement in many countries that a website is accessible to users with various disabilities such as visual impairment.  So be sure that your chosen CMS can publish content meeting relevant accessibility legislation.</p>
<p>Typically this means meeting the <a href="http://www.w3.org/TR/WCAG10/">WCA guidelines</a> with a double-A rating.</p>
<p><strong>10. Advanced Features</strong></p>
<p>Is your website going to be serving content in different languages, content that is targeted to a particular geographic region, or publishing content to multiple websites?  Does the CMS support the character set of all the target languages?</p>
<p>This makes the CMS implementation considerably more complex, and will narrow the choices quite considerably.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2009/09/03/choosing-a-cms-in-10-steps/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#8220;Organica&#8221; &#8211; a free HTML CSS template</title>
		<link>http://www.fullfatcode.com/2009/08/27/organica-a-free-html-css-template/</link>
		<comments>http://www.fullfatcode.com/2009/08/27/organica-a-free-html-css-template/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 00:12:50 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[HTML + CSS]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=106</guid>
		<description><![CDATA[Today I&#8217;m launching a new free HTML/CSS template called &#8220;Organica&#8221;. It has a fresh blue and green theme inspired by nature, with beautiful nature photography from photos8.com. It uses transparent PNGs so that it&#8217;s easy to customise the images, even though they have curved borders. Transparent PNG support was added for IE6 with the help [...]]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;m launching a new free HTML/CSS template called &#8220;Organica&#8221;.</p>
<p>It has a fresh blue and green theme inspired by nature, with beautiful nature photography from <a href="http://www.photos8.com" target="_blank">photos8.com</a>.</p>
<p>It uses transparent PNGs so that it&#8217;s easy to customise the images, even though they have curved borders.  Transparent PNG support was added for IE6 with the help of the excellent <a href="http://www.twinhelix.com/css/iepngfix/" target="_blank">TwinHelix PNG fix</a> which worked nicely.</p>
<p>Feel free to use in your own projects, just please leave the footer link intact &#8211; thanks!</p>
<p><a href="http://www.fullfatcode.com/wp-content/uploads/2009/08/organica.zip">Get it now (ZIP archive)</a></p>
<div id="attachment_108" class="wp-caption alignnone" style="width: 610px"><a href="http://www.fullfatcode.com/wp-content/uploads/2009/08/organica_small.jpg"><img class="size-full wp-image-108" title="Organica HTML and CSS template" src="http://www.fullfatcode.com/wp-content/uploads/2009/08/organica_small.jpg" alt="A fresh blue and green theme inspired by nature" width="600" height="600" /></a><p class="wp-caption-text">A fresh blue and green theme inspired by nature</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2009/08/27/organica-a-free-html-css-template/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JQuery Multiple file upload</title>
		<link>http://www.fullfatcode.com/2009/08/02/jquery-multiple-file-upload/</link>
		<comments>http://www.fullfatcode.com/2009/08/02/jquery-multiple-file-upload/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 13:23:14 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=97</guid>
		<description><![CDATA[I&#8217;ve been on the hunt for many years for a decent way of uploading multiple files at once via a browser-based upload form. Finally there is one that seems to do a great job, and be fairly easy to install &#8211; the JQuery Uploadify plugin. There&#8217;s a couple of &#8216;gotchas&#8217; that I came across and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been on the hunt for many years for a decent way of uploading multiple files at once via a browser-based upload form.  Finally there is one that seems to do a great job, and be fairly easy to install &#8211; the <a href="http://www.uploadify.com/">JQuery Uploadify </a>plugin.</p>
<p>There&#8217;s a couple of &#8216;gotchas&#8217; that I came across and thought I would share.</p>
<p>Firstly, if you use PHP sessions for your authentication, you&#8217;ll find that your PHP script that accepts the upload won&#8217;t have access to the current session.  This is because Flash gets given a different session ID.  One way to get around this problem is to manually send your PHP session id as one of the options, something like:</p>
<pre class="brush: jscript; title: ;">

'scriptData'  : {'sessid' : &lt;php echo session_id(); ?&gt;}
</pre>
<p>Then your script that accepts the file upload would require:</p>
<pre class="brush: php; title: ;">

session_id($_REQUEST['sessid']);
session_start();
</pre>
<p>Secondly, I found that for the &#8216;script&#8217; option, the plugin requires a relative path.  I don&#8217;t want to have to keep setting paths because they&#8217;re different in my development and live environment, so I did this:</p>
<pre class="brush: jscript; title: ;">

var rel_path     = location.href.split(/localhost|\.co\.uk|\.com|index\.php/)[1];
$('#uploadify').uploadify({
'script':         rel_path + 'upload_script.php'

// other options here...

})
</pre>
<p>This is a brilliant plugin &#8211; a big thank-you to the authors!</p>
<p>Update 09/09/2009:  after lots of hair-pulling/teeth-grinding/tea-drinking, the PHP sessions problem just couldn&#8217;t be resolved quickly on the live server so I adopted a different approach in the end:</p>
<ul>
<li>A singe use &#8216;upload authentication key&#8217; is generated each time you upload the file, and stored in the database along with the current user</li>
<li>Uploadify sends this key via the scriptData option</li>
<li>The script that accepts the file upload ignores PHP sessions, and instead looks in the database for the authentication key to verify the user that sent the file has access.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2009/08/02/jquery-multiple-file-upload/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fancy zapping some baddies?  Go ahead&#8230;</title>
		<link>http://www.fullfatcode.com/2009/08/01/flash-game-example-space-invader/</link>
		<comments>http://www.fullfatcode.com/2009/08/01/flash-game-example-space-invader/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 23:34:55 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=85</guid>
		<description><![CDATA[Check out this simple Flash game I developed below&#8230; Use cursor keys to get around and space bar to fire. Click to open in a new window]]></description>
			<content:encoded><![CDATA[<p>Check out this simple Flash game I developed below&#8230;  Use cursor keys to get around and space bar to fire.</p>
<p><a href="http://www.fullfatcode.com/wp-content/uploads/2009/08/game.swf" target="_blank">Click to open in a new window</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2009/08/01/flash-game-example-space-invader/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Future of web apps 2009</title>
		<link>http://www.fullfatcode.com/2009/07/30/future-of-web-apps-2009/</link>
		<comments>http://www.fullfatcode.com/2009/07/30/future-of-web-apps-2009/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 15:14:52 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=81</guid>
		<description><![CDATA[Just spotted the &#8220;Future of web apps&#8221; conference in London on 30th Sep &#8211; 2nd Oct 2009 &#8211; looks awesome!]]></description>
			<content:encoded><![CDATA[<p>Just spotted the &#8220;Future of web apps&#8221; conference in London on 30th Sep &#8211; 2nd Oct 2009 &#8211; looks awesome!</p>
<p><a href="http://events.carsonified.com/fowa/2009/london?utm_source=TV&amp;utm_medium=smallbanner&amp;utm_campaign=fowalondon"><img class="alignnone size-full wp-image-80" title="FOWA badge" src="http://www.fullfatcode.com/wp-content/uploads/2009/07/event_badge_01.jpg" alt="FOWA badge" width="224" height="119" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2009/07/30/future-of-web-apps-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A noob&#8217;s guide to PHP Doctrine</title>
		<link>http://www.fullfatcode.com/2009/06/30/a-noobis-guide-to-php-doctrine/</link>
		<comments>http://www.fullfatcode.com/2009/06/30/a-noobis-guide-to-php-doctrine/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 18:30:51 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[orm]]></category>

		<guid isPermaLink="false">http://www.fullfatcode.com/?p=77</guid>
		<description><![CDATA[This week I am a newbie to PHP Doctrine. So I thought I&#8217;d share some of the experiences I&#8217;ve had with it, not so much in a coding sense but in a &#8220;this is the cool stuff you can do with it&#8221; sense. Doctrine is an &#8216;object relational mapper&#8217; or ORM for short, letting you [...]]]></description>
			<content:encoded><![CDATA[<p>This week I am a newbie to <a href="http://www.doctrine-project.org/">PHP Doctrine</a>.  So I thought I&#8217;d share some of the experiences I&#8217;ve had with it, not so much in a coding sense but in a &#8220;this is the cool stuff you can do with it&#8221; sense.</p>
<p>Doctrine is an &#8216;object relational mapper&#8217; or ORM for short, letting you code your app in terms of the objects you require, without worrying too much about the underlying database table structure.  With SQL queries, a simple 2-dimensional table of rows and columns is returned.  Using an ORM, a multi-dimensional object or array can be returned with all the relationships between objects prepared for you.</p>
<p>In general I&#8217;m a bit of framework-sceptic, but I think this one really deserves a look as there&#8217;s some really powerful tools included.</p>
<p>Also the website is nicely designed and has pretty good documentation on it, which makes all the difference.</p>
<p>So here&#8217;s a list of 10 things I&#8217;ve learned about it this week, in no particular order:</p>
<ol>
<li>You can define your data structures using a simple YAML file, which while it sounds like some kind of novel pet food, is in fact dead easy to get to grips with and is very quick to type out.</li>
<li>Doctrine will create PHP model objects all ready to go from the YAML file <em>and </em>install the necessary database tables for you.</li>
<li>If you find yourself needing to change the data structure, you can do so in the YAML file and Doctrine will update the PHP scripts and the database tables aswell, while retaining the data &#8211; I think this is a great feature.</li>
<li>Doctrine can guess from the YAML file what the relationships are between objects/tables, and so far seems to do a great job of it.</li>
<li>If you don&#8217;t want to hand craft your YAML, you can also do various things like build the models from an existing database structure or vice versa</li>
<li>You can fetch data from one object and it fetches all the related data too, eg if I fetch a blog post and it fetches all the related comments at the same time.</li>
<li>You can use &#8220;Doctrine Query Language&#8221; or DQL, which is has a similar feel to SQL, but selects objects together with their relationships instead of a flat table of results.  Gone are the days of laboriously typing out JOIN statements: because you&#8217;ve described the data relationships in your YAML file, Doctrine automatically joins things together for you.  Nifty.</li>
<li>You can hook into the models that are automatically generated allowing you to, for example, modify queries on the fly before data is requested, or modify data as it&#8217;s returned.  This lets you reuse business logic efficiently that is always used on particular fields.</li>
<li>There are built-in behaviours such as &#8216;timestampable&#8217; or &#8216;sluggable&#8217; which automatically generate timestamp fields or URL slugs (eg &#8216;this-is-a-nice-blog&#8217;) for particular tables</li>
<li>It also has the usual suspects such as data validation &#8211; but I haven&#8217;t got to that yet&#8230;</li>
</ol>
<p>Right, that&#8217;s it for now &#8211; if I find out anything else interesting I&#8217;ll post it here!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fullfatcode.com/2009/06/30/a-noobis-guide-to-php-doctrine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

