<?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>Code No Evil</title>
	<atom:link href="http://www.codenoevil.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codenoevil.com</link>
	<description>No Monkey Business. Just Good Code.</description>
	<lastBuildDate>Wed, 12 Dec 2012 22:00:12 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Pass Additional ViewData to an ASP.NET MVC 4 Partial View While Propagating ModelState Errors</title>
		<link>http://www.codenoevil.com/pass-additional-viewdata-asp-net-mvc-4/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pass-additional-viewdata-asp-net-mvc-4</link>
		<comments>http://www.codenoevil.com/pass-additional-viewdata-asp-net-mvc-4/#comments</comments>
		<pubDate>Mon, 10 Sep 2012 17:48:30 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>

		<guid isPermaLink="false">http://www.codenoevil.com/?p=837</guid>
		<description><![CDATA[ASP.NET MVC 4 In my ASP.NET MVC 4 partial view, I was having an issue where VaidationSummary and VaidationMessageFor were coming up blank. I scratched my head on this for quite some time. I finally came across this entry at the MVC forums at MSDN. It turns out I wasn&#8217;t passing the ViewData from parent&#8230; <a href="http://www.codenoevil.com/pass-additional-viewdata-asp-net-mvc-4/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h2>ASP.NET MVC 4</h2>

<p>In my ASP.NET MVC 4 partial view, I was having an issue where <code>VaidationSummary</code> and <code>VaidationMessageFor</code> were coming up blank. I scratched my head on this for quite some time. I finally came across <a href="http://tro.pe/QytLFT">this entry</a> at the MVC forums at MSDN. It turns out I wasn&#8217;t passing the ViewData from parent view, but in fact my own fresh ViewData. This is how I had things before:</p>

<h2>The Wrong Way</h2>

<pre class="crayon-plain-tag">&lt;code&gt;@{
    Html.RenderPartial(&quot;_CreateEditDisplay&quot;, Model, new ViewDataDictionary { { &quot;Submit&quot;, true }, { &quot;Action&quot;, &quot;Edit&quot; }, { &quot;ReadOnly&quot;, false } });
}
&lt;/code&gt;</pre>

<h2>The Right Way</h2>

<p>I figured it out by doing this instead:</p>

<pre class="crayon-plain-tag">&lt;code&gt;@{
    Html.ViewData.Add(new KeyValuePair&amp;lt;string, object&amp;gt;(&quot;Submit&quot;, true));
    Html.ViewData.Add(new KeyValuePair&amp;lt;string, object&amp;gt;(&quot;Action&quot;, &quot;Edit&quot;));
    Html.ViewData.Add(new KeyValuePair&amp;lt;string, object&amp;gt;(&quot;ReadOnly&quot;, false));

    Html.RenderPartial(&quot;_CreateEditDisplay&quot;, Model, Html.ViewData);
}
&lt;/code&gt;</pre>

<p>Basically what we have here is the original ViewData from the parent view with my additional add-ons that are passed to the partial view. Once I made this change, the ModelState is propagated to the partial view and <code>VaidationSummary</code> and <code>VaidationMessageFor</code> are outputting the desired results.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/pass-additional-viewdata-asp-net-mvc-4/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Anything Worth Doing Is Worth Overdoing or: Extending an Amazon AWS CloudFormation Template</title>
		<link>http://www.codenoevil.com/extending-an-amazon-aws-cloudformation-template/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=extending-an-amazon-aws-cloudformation-template</link>
		<comments>http://www.codenoevil.com/extending-an-amazon-aws-cloudformation-template/#comments</comments>
		<pubDate>Tue, 29 May 2012 03:12:26 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>

		<guid isPermaLink="false">http://www.codenoevil.com/?p=799</guid>
		<description><![CDATA[The need for stability Meg&#8217;s sites, megbitton.com and soulsimagined.com have uptime requirements that far and away exceed those of mine. Almost the entirety of her business is predicated on a persistent Internet presence. As I&#8217;m sure you understand, a few minutes of downtime could lead to a belief that she&#8217;s no longer in business. This&#8230; <a href="http://www.codenoevil.com/extending-an-amazon-aws-cloudformation-template/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h2>The need for stability</h2>

<p>Meg&#8217;s sites, <a href="http://www.megbitton.com">megbitton.com</a> and <a href="http://www.soulsimagined.com">soulsimagined.com</a> have uptime requirements that far and away exceed those of mine. Almost the entirety of her business is predicated on a persistent Internet presence. As I&#8217;m sure you understand, a few minutes of downtime could lead to a belief that she&#8217;s no longer in business. This quote from The Social Network says it all:</p>

<blockquote>
  <p>Mark Zuckerberg: [speaking frantically, almost hysterical] Without money the site can&#8217;t function. Okay, let me tell you the difference between Facebook and everyone else, we don&#8217;t crash EVER! If those servers are down for even a day, our entire reputation is irreversibly destroyed! Users are fickle, Friendster has proved that. Even a few people leaving would reverberate through the entire user base. The users are interconnected, that is the whole point. College kids are online because their friends are online, and if one domino goes, the other dominos go, don&#8217;t you get that? I am not going back to the Caribbean Night at AEPi!</p>
</blockquote>

<p>While I certainly appreciate the job that <a href="http://www.dreamhost.com/r.cgi?18127">Dreamhost</a> does in keeping their servers and vis-à-vis their network available to the Internet; it&#8217;s not at a level of fault tolerance that you can obtain from an <a href="http://aws.amazon.com">Amazon Web Services</a> EC2 instance. <a href="http://aws.amazon.com/ec2/">EC2</a> stands for Elastic Cloud Compute and is, for all intents and purposes, a virtual private server capable of hosting an OS such as Windows or Linux. What makes an EC2 instance special is two-fold. First, you can dynamically expand the number of instances running based on demand. Second, and this is the real crux of the issue, you can host multiple EC2 instances in disparate data centers and load balance across all instances. That is where the reliability comes into play.</p>

<p>Amazon is making a big play in this space and has a myriad of options available within AWS. I&#8217;m not going to go into great detail, but I&#8217;ll have you know that you can host databases, load balancers, DNS, message queues, notification systems, and a whole host of other services. Here is a quick screenshot of the toolbar icons that are available in the AWS console.</p>

<p><img src="http://eight.cdn-codenoevil.com/wp-content/uploads/2012/05/Screen-Shot-2012-05-28-at-9.15.03-PM.png" alt="AWS Console Toolbar Icons" /></p>

<p>As a quick aside, I&#8217;m using <a href="http://aws.amazon.com/s3/">S3</a> and <a href="http://aws.amazon.com/cloudfront/">CloudFront</a> as my CDN for this site.</p>

<h2>CloudFormation, AWS and the free Micro tier</h2>

<p>In order for users to become acquainted with AWS, Amazon makes an EC2 micro instance free for one year. Beside the obvious which is a free VPS for one year, what it really does is allow you to drive AWS like a rented mule. Create the instance, muck up the OS &#8220;<em>real good</em>&#8221; and then kill it and create a new one. This is where I started to have fun with another component of AWS titled <a href="http://aws.amazon.com/cloudformation/">CloudFormation</a>. From the CloudFormation site:</p>

<blockquote>
  <p>AWS CloudFormation gives developers and systems administrators an easy way to create and manage a collection of related AWS resources, provisioning and updating them in an orderly and predictable fashion.</p>
</blockquote>

<p>The templates are JSON, and have a defined structure to them. The CloudFormation <a href="http://docs.amazonwebservices.com/AWSCloudFormation/latest/UserGuide/Welcome.html">documentation</a> has a lot of detaills and a must for getting around. I&#8217;m not going to go into those details because I want to jump to the gist of this post, which is taking the <a href="https://s3.amazonaws.com/cloudformation-templates-us-east-1/WordPress_Single_Instance_With_RDS.template">Single EC2 Instance web server with Amazon RDS database instance</a> sample template and adding additional CloudFormation functionality.</p>

<h2>AWS::CloudFormation::Init</h2>

<p>A key feature in templates is the ability to perform actions against the EC2 instance after it&#8217;s created. You can do the following:</p>

<ul>
<li>Install packages such as <code>httpd</code> using yum</li>
<li>Unpack one or more zip or tarballs into a defined location</li>
<li>Perform command line operations</li>
<li>Create files</li>
<li>Start services such as httpd</li>
<li>Add users</li>
<li>Manage user groups</li>
</ul>

<p>AWS::CloudFormation::Init is a sub-resource created within the template under the EC2 instance. AWS::CloudFormation::Init is passed as metadata to the EC2 resource telling it what to do when when its fired up. AWS::CloudFormation::Init is started by a call to an AWS specific script that is installed within the default Linux instance, <code>cfn-init</code>. This script is called by an Bash script defined in the template. The Bash script, pushed in the UserData field of the EC2 instance properties, also contains a number of functions in the sample template. The original EC2 resource Properties looked like this:</p>

<h3>UserData</h3>

<pre class="crayon-plain-tag">&lt;code&gt;  &quot;Properties&quot;: {
    &quot;ImageId&quot; : { &quot;Fn::FindInMap&quot; : [ &quot;AWSRegionArch2AMI&quot;, { &quot;Ref&quot; : &quot;AWS::Region&quot; },
                      { &quot;Fn::FindInMap&quot; : [ &quot;AWSInstanceType2Arch&quot;, { &quot;Ref&quot; : &quot;InstanceType&quot; }, &quot;Arch&quot; ] } ] },
    &quot;InstanceType&quot;   : { &quot;Ref&quot; : &quot;InstanceType&quot; },
    &quot;SecurityGroups&quot; : [ {&quot;Ref&quot; : &quot;WebServerSecurityGroup&quot;} ],
    &quot;KeyName&quot;        : { &quot;Ref&quot; : &quot;KeyName&quot; },
    &quot;UserData&quot;       : { &quot;Fn::Base64&quot; : { &quot;Fn::Join&quot; : [&quot;&quot;, [
      &quot;#!/bin/bash\n&quot;,
      &quot;yum update -y aws-cfn-bootstrap\n&quot;,

      &quot;/opt/aws/bin/cfn-init -s &quot;, { &quot;Ref&quot; : &quot;AWS::StackName&quot; }, &quot; -r WebServer &quot;,
      &quot;         --access-key &quot;, { &quot;Ref&quot; : &quot;HostKeys&quot; },
      &quot;         --secret-key &quot;, {&quot;Fn::GetAtt&quot;: [&quot;HostKeys&quot;, &quot;SecretAccessKey&quot;]},
      &quot;         --region &quot;, { &quot;Ref&quot; : &quot;AWS::Region&quot; }, &quot;\n&quot;,

      &quot;/opt/aws/bin/cfn-signal -e $? '&quot;, { &quot;Ref&quot; : &quot;WaitHandle&quot; }, &quot;'\n&quot;,

      &quot;# Setup correct file ownership\n&quot;,
      &quot;chown -R apache:apache /var/www/html/wordpress\n&quot;

    ]]}} 
&lt;/code&gt;</pre>

<p>This script is updating the AWS scripts to the latest version, starting AWS::CloudFormation::Init, and then tweaking the WordPress install. WordPress was installed from a tarball into the web root of the server in this section of the template:</p>

<h3>Metadata</h3>

<pre class="crayon-plain-tag">&lt;code&gt;&quot;AWS::CloudFormation::Init&quot; : {
      &quot;config&quot; : {
        &quot;packages&quot; : {
          &quot;yum&quot; : {
            &quot;httpd&quot;     : [],
            &quot;php&quot;       : [],
            &quot;php-mysql&quot; : []
          }
        },
        &quot;sources&quot; : {
          &quot;/var/www/html&quot; : &quot;http://wordpress.org/latest.tar.gz&quot;
        },
        &quot;files&quot; : {
          &quot;/var/www/html/wordpress/wp-config.php&quot; : {
            &quot;content&quot; : { &quot;Fn::Join&quot; : [&quot;&quot;, [
              &quot;&amp;lt;?php\n&quot;,
              &quot;define('DB_NAME',          '&quot;, {&quot;Ref&quot; : &quot;DBName&quot;}, &quot;');\n&quot;,
              &quot;define('DB_USER',          '&quot;, {&quot;Ref&quot; : &quot;DBUsername&quot;}, &quot;');\n&quot;,
              &quot;define('DB_PASSWORD',      '&quot;, {&quot;Ref&quot; : &quot;DBPassword&quot; }, &quot;');\n&quot;,
              &quot;define('DB_HOST',          '&quot;, {&quot;Fn::GetAtt&quot; : [&quot;DBInstance&quot;, &quot;Endpoint.Address&quot;]},&quot;');\n&quot;,
              &quot;define('DB_CHARSET',       'utf8');\n&quot;,
              &quot;define('DB_COLLATE',       '');\n&quot;,
              &quot;define('AUTH_KEY',         'f@A17vs{ mO0}:&amp;amp;I,6SB.QzV`E?!`/tN5:~GZX%=@ZA%!_T0-]9&amp;gt;g]4ll6~,6G|R');\n&quot;,
              &quot;define('SECURE_AUTH_KEY',  'gTFTI|~rYHY)|mlu:Cv7RN]GQ^3ngyUbw;L0o!12]0c-ispR&amp;lt;-yt3qj]xjquz^&amp;amp;9');\n&quot;,
              &quot;define('LOGGED_IN_KEY',    'Jd:HG9M)1p5t2&amp;lt;v~+R-vd{p-Q*|*RB^&amp;amp;PUI{vIrydAEEiV!{HS{jN:nErCmLv`p}');\n&quot;,
              &quot;define('NONCE_KEY',        '4aMj4KZV;,Gu7(B|qOCve[c5?*J5x1+x93i:Ey6hh/6jXh+V_{V4+hw!qE^d*U,-');\n&quot;,
              &quot;define('AUTH_SALT',        '_Y_&amp;amp;8m)FH)Cns)8}Yb8b88KDSn:p1#p(qBa&amp;lt;~VW&amp;amp;Y1v}P.*9/8S8@P`{mkNxV lC');\n&quot;,
              &quot;define('SECURE_AUTH_SALT', '%nG3Ag41^Lew5c86,#zbN:yPFs.GA5a)z5*:Oce1&amp;gt;v6uF~D`,.o1pzS)F8[bM9i[');\n&quot;,
              &quot;define('LOGGED_IN_SALT',   '~K&amp;lt;y+Ly+_Ww1~dtq&amp;gt;;rSQ^+{P5/k|=!]k%RXAF-Y@XMY6GSp+wJ5{(|rCzaWjZ%/');\n&quot;,
              &quot;define('NONCE_SALT',       ',Bs_*Y9:b/1Z:apVLHtz35uim|okkA,b|Jt[-&amp;amp;Nla=T{&amp;lt;l_#D?~6Tj-.2.]FonI~');\n&quot;,
              &quot;define('WPLANG'            , '');\n&quot;,
              &quot;define('WP_DEBUG'          , false);\n&quot;,
              &quot;$table_prefix  = 'wp_';\n&quot;,
              &quot;if ( !defined('ABSPATH') )\n&quot;,
              &quot;    define('ABSPATH', dirname(__FILE__) . '/');\n&quot;,
              &quot;require_once(ABSPATH . 'wp-settings.php');\n&quot;
            ]] },
            &quot;mode&quot; : &quot;000644&quot;,
            &quot;owner&quot; : &quot;root&quot;,
            &quot;group&quot; : &quot;root&quot;
          }
        },
        &quot;services&quot; : {
          &quot;sysvinit&quot; : {
            &quot;httpd&quot;    : { &quot;enabled&quot; : &quot;true&quot;, &quot;ensureRunning&quot; : &quot;true&quot; },
            &quot;sendmail&quot; : { &quot;enabled&quot; : &quot;false&quot;, &quot;ensureRunning&quot; : &quot;false&quot; }
          }
        }
      }
&lt;/code&gt;</pre>

<p>This segment of the original template creates the WordPress <code>wp-config.php</code> file with references to the RDS resource that is also generated by the template, installs the necessary packages on the server, and sets up the proper services to run as daemons. The first component of the template that I took issue with was that every install was going to have the same random keys. Fortunately, WordPress has a service that will generate these values for you. All you need to do is call <a href="https://api.wordpress.org/secret-key/1.1/salt/">https://api.wordpress.org/secret-key/1.1/salt/</a> and WordPress will return to you the necessary segments to add to your <code>wp-config.php</code>. First problem to solve, how do I get these values into the <em>middle</em> of the file. Why the middle? I tried a simple append but the WordPress install didn&#8217;t see them. After quite a bit of trial and error, I wrote a Perl script that is called from the command line. I did this because I didn&#8217;t want to leave my custom script as a file on the server.</p>

<h3>Perl file mangling</h3>

<pre class="crayon-plain-tag">&lt;code&gt;              &quot;command&quot; : { &quot;Fn::Join&quot; : [&quot;&quot;, [
                &quot;perl - /var/www/html/wp-config.php &amp;lt;&amp;lt;'EOF'\n&quot;,
                &quot;use strict;\n&quot;,
                &quot;use warnings;\n&quot;,
                &quot;\n&quot;,
                &quot;$^I = '.bak';\n&quot;,
                &quot;my $keys = `curl -sS https://api.wordpress.org/secret-key/1.1/salt/`;\n&quot;,
                &quot;while(&amp;lt;&amp;gt;) {\n&quot;,
                &quot;  if (\/\\{KEYS_TOKEN\\}\/){ \n&quot;,
                &quot;    print $keys; \n&quot;,
                &quot;  } else { \n&quot;,
                &quot;    print; \n&quot;,
                &quot;  }\n&quot;,
                &quot;}\n&quot;,
                &quot;EOF\n&quot;
              ]]}
&lt;/code&gt;</pre>

<p>This script looks for a token that I inserted into the <code>wp-config.php</code> file. This snippet is part of a larger section of the template. Since <em>things</em> have to happen in order, CloudFormation templates allow you to have sets of config options, run them in specific order, and then run commands in order. Here is the larger snippet.</p>

<h3>configSets</h3>

<pre class="crayon-plain-tag">&lt;code&gt;      &quot;configSets&quot; : {
          &quot;default&quot; : [ &quot;first&quot;, &quot;second&quot; ]
        },
      &quot;second&quot; : {
          &quot;commands&quot; : {
            &quot;a&quot; : {
              &quot;command&quot; : &quot;mv /var/www/html/wordpress/* /var/www/html/wordpress/.??* /var/www/html/ ; rmdir /var/www/html/wordpress&quot;
            },
            &quot;b&quot; : {
              &quot;command&quot; : &quot;chown -R apache:apache /var/www/html ; find /var/www/html -type d -exec chmod 770 {} + ; find /var/www/html -type f -exec chmod 660 {} +&quot;
            },
            &quot;c&quot; : {
              &quot;command&quot; : { &quot;Fn::Join&quot; : [&quot;&quot;, [
                &quot;perl - /var/www/html/wp-config.php &amp;lt;&amp;lt;'EOF'\n&quot;,
                &quot;use strict;\n&quot;,
                &quot;use warnings;\n&quot;,
                &quot;\n&quot;,
                &quot;$^I = '.bak';\n&quot;,
                &quot;my $keys = `curl -sS https://api.wordpress.org/secret-key/1.1/salt/`;\n&quot;,
                &quot;while(&amp;lt;&amp;gt;) {\n&quot;,
                &quot;  if (\/\\{KEYS_TOKEN\\}\/){ \n&quot;,
                &quot;    print $keys; \n&quot;,
                &quot;  } else { \n&quot;,
                &quot;    print; \n&quot;,
                &quot;  }\n&quot;,
                &quot;}\n&quot;,
                &quot;EOF\n&quot;
              ]]}
            }
          }
        },
      &quot;first&quot; : {
        &quot;packages&quot; : {
          &quot;yum&quot; : {
            &quot;httpd&quot;     : [],
            &quot;php&quot;       : [],
            &quot;php-mysql&quot; : [],
            &quot;mysql&quot;     : []
          }
        },
        &quot;sources&quot; : {
          &quot;/var/www/html&quot; : &quot;http://wordpress.org/latest.tar.gz&quot;
        },
        &quot;files&quot; : {
          &quot;/var/www/html/wordpress/wp-config.php&quot; : {
            &quot;content&quot; : { &quot;Fn::Join&quot; : [&quot;&quot;, [
              &quot;&amp;lt;?php\n&quot;,
              &quot;define('DB_NAME',          '&quot;, {&quot;Ref&quot; : &quot;DBName&quot;}, &quot;');\n&quot;,
              &quot;define('DB_USER',          '&quot;, {&quot;Ref&quot; : &quot;DBUsername&quot;}, &quot;');\n&quot;,
              &quot;define('DB_PASSWORD',      '&quot;, {&quot;Ref&quot; : &quot;DBPassword&quot; }, &quot;');\n&quot;,
              &quot;define('DB_HOST',          '&quot;, {&quot;Fn::GetAtt&quot; : [&quot;DBInstance&quot;, &quot;Endpoint.Address&quot;]},&quot;');\n&quot;,
              &quot;define('DB_CHARSET',       'utf8');\n&quot;,
              &quot;define('DB_COLLATE',       '');\n&quot;,
              &quot;define('WPLANG'            , '');\n&quot;,
              &quot;define('WP_DEBUG'          , false);\n&quot;,
              &quot;{KEYS_TOKEN}\n&quot;,
              &quot;$table_prefix  = 'wp_';\n&quot;,
              &quot;if ( !defined('ABSPATH') )\n&quot;,
              &quot;    define('ABSPATH', dirname(__FILE__) . '/');\n&quot;,
              &quot;require_once(ABSPATH . 'wp-settings.php');\n&quot;
            ]] },
            &quot;mode&quot; : &quot;000644&quot;,
            &quot;owner&quot; : &quot;root&quot;,
            &quot;group&quot; : &quot;root&quot;
          },
          &quot;/etc/cfn/cfn-credentials&quot; : {
            &quot;content&quot; : { &quot;Fn::Join&quot; : [&quot;&quot;, [
              &quot;AWSAccessKeyId=&quot;, { &quot;Ref&quot; : &quot;WebServerKeys&quot; }, &quot;\n&quot;,
              &quot;AWSSecretKey=&quot;, {&quot;Fn::GetAtt&quot;: [&quot;WebServerKeys&quot;, &quot;SecretAccessKey&quot;]}, &quot;\n&quot;
            ]]},
            &quot;mode&quot;    : &quot;000400&quot;,
            &quot;owner&quot;   : &quot;root&quot;,
            &quot;group&quot;   : &quot;root&quot;
          },

          &quot;/etc/cfn/cfn-hup.conf&quot; : {
            &quot;content&quot; : { &quot;Fn::Join&quot; : [&quot;&quot;, [
              &quot;[main]\n&quot;,
              &quot;stack=&quot;, { &quot;Ref&quot; : &quot;AWS::StackName&quot; }, &quot;\n&quot;,
              &quot;credential-file=/etc/cfn/cfn-credentials\n&quot;,
              &quot;region=&quot;, { &quot;Ref&quot; : &quot;AWS::Region&quot; }, &quot;\n&quot;
            ]]},
            &quot;mode&quot;    : &quot;000400&quot;,
            &quot;owner&quot;   : &quot;root&quot;,
            &quot;group&quot;   : &quot;root&quot;
          },

          &quot;/etc/cfn/hooks.d/cfn-auto-reloader.conf&quot; : {
            &quot;content&quot;: { &quot;Fn::Join&quot; : [&quot;&quot;, [
              &quot;[cfn-auto-reloader-hook]\n&quot;,
              &quot;triggers=post.update\n&quot;,
              &quot;path=Resources.WebServerEc2Instance.Metadata.AWS::CloudFormation::Init\n&quot;,
              &quot;action=/opt/aws/bin/cfn-init -s &quot;, { &quot;Ref&quot; : &quot;AWS::StackName&quot; },
              &quot;              -r WebServerEc2Instance &quot;,
              &quot;              -c default&quot;,
              &quot;              --credential-file /etc/cfn/cfn-credentials &quot;,
              &quot;              --region     &quot;, { &quot;Ref&quot; : &quot;AWS::Region&quot; }, &quot;\n&quot;,
              &quot;runas=root\n&quot;
            ]]}
          }              
        },
&lt;/code&gt;</pre>

<p>You&#8217;ll notice now there are first and a second config sections. They appear backwards in the JSON, however if you look at the configSets (<a href="http://tro.pe/KYlIin">documentation</a>), the sections are called in the correct order. Also commands are called in alphabetical order, so I just named them a, b, c, and so on. The other commands I perform is moving WordPress out of a folder under the webroot, setting the correct file and folder permissions, and of course the mangling of the <code>wp-config.php</code> file.</p>

<h3>cfn-hup</h3>

<p>The last added item to the template is the use of <code>cfn-hup</code>. <code>cfn-hup</code> is an optional script that can run as a daemon and look for template updates that are pushed to the server. When changes occur, <code>cfn-hup</code> reads its respective config files and performs the prescribed actions defined within. I added some <a href="http://tro.pe/KYo0xG">boilerplate</a> code into the template from the CloudFormation docs.</p>

<h3>userData Redux</h3>

<pre class="crayon-plain-tag">&lt;code&gt;    &quot;UserData&quot;       : 
    { 
      &quot;Fn::Base64&quot; : 
      { 
        &quot;Fn::Join&quot; : 
        [
          &quot;&quot;, 
          [
            &quot;#!/bin/bash\n&quot;,
            &quot;yum update -y aws-cfn-bootstrap\n&quot;,

            &quot;# Helper function\n&quot;,
            &quot;function error_exit\n&quot;,
            &quot;{\n&quot;,
            &quot;  /opt/aws/bin/cfn-signal -e 1 -r \&quot;$1\&quot; '&quot;, { &quot;Ref&quot; : &quot;WaitHandle&quot; }, &quot;'\n&quot;,
            &quot;  exit 1\n&quot;,
            &quot;}\n&quot;,

            &quot;/opt/aws/bin/cfn-init -s &quot;, { &quot;Ref&quot; : &quot;AWS::StackName&quot; }, &quot; -r WebServerEc2Instance -c default&quot;,
            &quot;         --access-key &quot;, { &quot;Ref&quot; : &quot;HostKeys&quot; },
            &quot;         --secret-key &quot;, {&quot;Fn::GetAtt&quot;: [&quot;HostKeys&quot;, &quot;SecretAccessKey&quot;]},
            &quot;         --region &quot;, { &quot;Ref&quot; : &quot;AWS::Region&quot; },
            &quot; || error_exit 'Failed to run cfn-init.'\n&quot;,

            &quot;# Start up the cfn-hup daemon to listen for changes\n&quot;,
            &quot;/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n&quot;,

            &quot;# Now that Wordpress is complete, perform a full yum update\n&quot;,
            &quot;#yum -y update&quot;,
            &quot;# || error_exit 'Failed to yum update.'\n&quot;,

            &quot;# All is well so signal success\n&quot;,
            &quot;/opt/aws/bin/cfn-signal -e 0 -r \&quot;Wordpress installation complete.\&quot; '&quot;, { &quot;Ref&quot; : &quot;WaitHandle&quot; }, &quot;'\n&quot;
          ]
        ]
      }
    }        
&lt;/code&gt;</pre>

<p>Here is the update Bash script that is run after install. Besides starting init, it also starts up cfn-hup. There&#8217;s also a full <code>yum -y update</code> in there, however for testing, it&#8217;s commented out.</p>

<h2>Complete Template</h2>

<p>You&#8217;re welcome to a copy of the script, and it&#8217;s in a ZIP file below. I also started a GitHub <a href="https://github.com/davidbitton/CloudFormationTemplates">repo</a> with this template and any others I create in the future. Thanks!</p>

<p><a href="http://seven.cdn-codenoevil.com/wp-content/uploads/2012/05/WordPress_Single_Instance_With_RDS_cne_command.template.zip">Download Here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/extending-an-amazon-aws-cloudformation-template/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Seek and Ye Shall Find or: Why I Wrote an Adobe Photoshop Lightroom Spotlight Importer</title>
		<link>http://www.codenoevil.com/why-i-wrote-a-lightroom-spotlight-importer/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-i-wrote-a-lightroom-spotlight-importer</link>
		<comments>http://www.codenoevil.com/why-i-wrote-a-lightroom-spotlight-importer/#comments</comments>
		<pubDate>Thu, 10 May 2012 00:44:58 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>

		<guid isPermaLink="false">http://www.codenoevil.com/?p=657</guid>
		<description><![CDATA[What catalog is that file in? That&#8217;s what I hear often from my wife Meg; a professional photographer. Meg uses Adobe Photoshop Lightroom for cataloging the pictures she takes for her business as well as the pictures she take of our family. An underlying frustration that I find with Lightroom is the fact that photos&#8230; <a href="http://www.codenoevil.com/why-i-wrote-a-lightroom-spotlight-importer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h4>What catalog is that file in?</h4>

<p>That&#8217;s what I hear often from my wife Meg; a professional photographer. Meg uses <a href="http://tro.pe/IDEGGu" title="Adobe Photoshop Lightroom">Adobe Photoshop Lightroom</a> for cataloging the pictures she takes for her <a href="http://tro.pe/IDEQhf" title="Meg Bitton Photography">business</a> as well as the pictures she take of our family. An underlying frustration that I find with Lightroom is the fact that photos become lost inside different catalogs on your hard drive, and Lightroom lacks the ability to search <em>across</em> catalogs. Some photographers believe the answer is to have a few monolithic catalogs. While these catalogs may contain everything in one searchable database, the catalogs become slow and unwieldy in a few short gigs of data. My answer is to have many small catalogs and harness the great search capabilities within the Mac OS &#8212; <a href="http://tro.pe/IDFbAn" title="Spotlight">Spotlight</a>. One small problem, Spotlight doesn&#8217;t inherently know how to index a Lightroom <code>.lrcat</code> file. In order to overcome this shortcoming, I wrote my own Spotlight plugin; something called an importer (See the <a href="http://tro.pe/K0RtTG" title="Spotlight Importer Programming Guide">Spotlight Importer Programming Guide</a>).</p>

<h4>SQLite</h4>

<p>Lightroom catalog files are actually <a href="http://tro.pe/K0QToL" title="SQLite">SQLite</a> databases and therefore extracting the necessary data was quite simple. I first used <a href="http://tro.pe/KGhvAt" title="SQLite Manager">SQLite Manager</a> in Firefox to examine the database. I came up with the following simple query to get at the filenames I would need to pass to Spotlight:</p>

<pre class="crayon-plain-tag">&lt;code&gt;SELECT originalFilename FROM AgLibraryFile
&lt;/code&gt;</pre>

<p>The next step was to run this query from within Objective-C. After using the familiar <a href="http://tro.pe/KGi11r" title="OmniSQLite">OmniSQLite</a> framework from the larger <a href="http://tro.pe/KGi11r" title="OmniGroup">OmniGroup</a> framework, I settled on a much smaller wrapper, <a href="http://tro.pe/K0U5B1" title="FMDB">FMDB</a>.</p>

<h4>Importer</h4>

<p>It took several days before I wrapped my head around Spotlight and the necessary components of an importer. Probably the most difficult concept to understand was <a href="http://tro.pe/IDFL1a" title="Uniform Type Identifiers">Uniform Type Identifiers</a> (UTI). Adobe does not identify a UTI for their catalog files. I had to create my own in order for Spotlight to identify the files and know what importer to use in order to index Lightroom catalogs. I came up with <code>com.adobe.lightroom.library</code>. This UTI is in the <code>Info.plist</code> file of my importer under the <code>Exported Type UTIs</code> section.</p>

<h4>Packaging</h4>

<p>Take note that the package I created for installing the importer places the importer in <code>~/Library/Spotlight</code>. I chose the user&#8217;s home directory because I can install it without the need for a password. I also run this command</p>

<pre class="crayon-plain-tag">&lt;code&gt;/usr/bin/mdimport -r ~/Library/Spotlight/LightroomSpotlightImporter.mdimporter
&lt;/code&gt;</pre>

<p>after install. That causes Spotlight to index files already on disk. See <a href="http://tro.pe/IDIk3h">here</a> for more info.</p>

<h4>Source Code</h4>

<p>The codes speaks well for itself and that is why the source is open and hosted at Github. I also created a nice Github <a href="http://tro.pe/JeDP3V" title="Project Pages">project page</a> for the code. You can find the page <a href="http://tro.pe/IDGBLa" title="Lightroom Spotlight Importer">here</a> and the source code <a href="http://tro.pe/KkhPlu" title="Lightroom Spotlight Importer">here</a>.</p>

<h4>Screenshot</h4>

<p>Here is the importer in use:</p>

<p><img src="http://seven.cdn-codenoevil.com/wp-content/uploads/2012/05/Screen-Shot-2012-05-09-at-8.39.59-PM.png" alt="screenshot" /></p>

<h2>Download</h2>

<p><a href="http://tro.pe/MTGD6J">Download the installer package</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/why-i-wrote-a-lightroom-spotlight-importer/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Absence Makes the Heart Grow Fonder or: Performing an XSLT Transformation on the Server</title>
		<link>http://www.codenoevil.com/absence-makes-the-heart-grow-fonder-or-performing-an-xslt-transformation-on-the-server/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=absence-makes-the-heart-grow-fonder-or-performing-an-xslt-transformation-on-the-server</link>
		<comments>http://www.codenoevil.com/absence-makes-the-heart-grow-fonder-or-performing-an-xslt-transformation-on-the-server/#comments</comments>
		<pubDate>Sat, 28 Apr 2012 03:26:52 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>

		<guid isPermaLink="false">http://www.codenoevil.com/?p=624</guid>
		<description><![CDATA[The MultiMarkdown ToC Do you ever feel like you&#8217;re never finished? I do, and I&#8217;m not happy with the fact that I haven&#8217;t been able to make Scrivener trigger the mmd-xslt script following a compile to MultiMarkdown HTML. Fine. As with the original XML epiphany, I knew there had to be code to perform an&#8230; <a href="http://www.codenoevil.com/absence-makes-the-heart-grow-fonder-or-performing-an-xslt-transformation-on-the-server/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h4>The MultiMarkdown ToC</h4>

<p>Do you ever feel like you&#8217;re never finished? I do, and I&#8217;m not happy with the fact that I haven&#8217;t been able to make <a href="http://tro.pe/fe48d5">Scrivener</a> trigger the <code>mmd-xslt</code> script following a compile to MultiMarkdown HTML. Fine. As with the original XML epiphany, I knew there had to be code to perform an XSLT transformation in PHP on the server. Certainly there is, and my <code>content-doc.php</code> content template has further evolved into an XSLT transformation powerhouse. If a custom variable is provided with a path to the XSLT file on disk, and that files exists, the code transforms the XML using the provided XSLT style sheet. Here is a snippet:</p>

<pre class="crayon-plain-tag">&lt;code&gt;&amp;lt;header class=&quot;page-header&quot;&amp;gt;
    &amp;lt;?php
    $title = get_the_title();

    $docs_path = get_post_meta(get_the_ID(), 'docs_path', true);
    if($docs_path &amp;amp;&amp;amp; file_exists($docs_path)) {
        libxml_use_internal_errors(true);
        $xml = simplexml_load_file($docs_path);
        foreach (libxml_get_errors() as $error) {
            error_log($error-&amp;gt;message);
        }
        if($xml) {
            $title = $xml-&amp;gt;head-&amp;gt;title;
            $xslt_path = get_post_meta(get_the_ID(), 'xslt_path', true);
            if($xslt_path &amp;amp;&amp;amp; file_exists($xslt_path)) {
                $xslt = simplexml_load_file($xslt_path);
                foreach (libxml_get_errors() as $error) {
                    error_log($error-&amp;gt;message);
                }
                if($xslt) { 
                    $proc = new XSLTProcessor;
                    $proc-&amp;gt;importStyleSheet($xslt);
                    $xml = simplexml_import_dom($proc-&amp;gt;transformToDoc($xml));

                }
            }
        }
    }

    printf('&amp;lt;h1 class=&quot;entry-title&quot;&amp;gt;%s&amp;lt;/h1&amp;gt;', $title);
    ?&amp;gt;
&amp;lt;/header&amp;gt;&amp;lt;!-- .entry-header --&amp;gt;
&lt;/code&gt;</pre>

<h4>Notes</h4>

<p>Something to take note of in the PHP code. <code>transformToDoc</code> returns a <code>DOMDocument</code> object and the <code>$xml</code> variable contains a <code>SimpleXMLElement</code> object returned by the <code>simplexml_load_file()</code> method. If you recall, we insert the XML into the page by echoing the proper child element using the <code>asXml()</code> method. Therefore in order to leave that code intact, I import the DOMDocument back into <code>$xml</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/absence-makes-the-heart-grow-fonder-or-performing-an-xslt-transformation-on-the-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Au Contraire, Mon Frère or: Putting the &#8216;X&#8217; in XHTML</title>
		<link>http://www.codenoevil.com/au-contraire-mon-frere-or-putting-the-x-in-xhtml/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=au-contraire-mon-frere-or-putting-the-x-in-xhtml</link>
		<comments>http://www.codenoevil.com/au-contraire-mon-frere-or-putting-the-x-in-xhtml/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 02:46:38 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>

		<guid isPermaLink="false">http://www.codenoevil.com/?p=580</guid>
		<description><![CDATA[To snippet or not to snippet My last post spoke of the need to use a snippet of XHTML in order to include it in a WordPress Page. This rule was short-lived. Why am I recanting my story? I switched to MultiMarkdown 3 and attempted the use its XSLT transformation capabilities; something of which requires&#8230; <a href="http://www.codenoevil.com/au-contraire-mon-frere-or-putting-the-x-in-xhtml/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>To snippet or not to snippet</h3>

<p>My last <a href="/archives/557">post</a> spoke of the need to use a snippet of XHTML in order to include it in a WordPress Page. This rule was short-lived. Why am I recanting my story? I switched to <a href="http://tro.pe/IpLy7O">MultiMarkdown</a> 3 and attempted the use its XSLT transformation capabilities; something of which requires an entire XHTML file (well-formed XML). The process in which one attempts an XSLT transformation with MMD3 is not an easy one at first glance. This is largely because I have yet to see how Scrivener can trigger MMD3 to perform the task at the completion of a successful compile. In order for Scrivener to be aware of the presence of MMD3 (Scrivener ships with MMD 2), an install of the MMD 3 Support <a href="http://tro.pe/IpdFET">package</a> is required. This package installs in <code>/Library/Application Support/MultiMarkdown</code>. Scrivener is inherently aware of the files in this location, and makes use of them in lieu of the MMD 2 files contained within its app package. One small problem, according to the MMD 3 <a href="http://tro.pe/JAoWaZ">docs</a>, the <code>XHTML XSLT</code> metadata tag has been removed from the spec.</p>

<p>In the absence of the <code>XHTML XSLT: xhtml-toc-h2.xslt</code> metadata tag, I had to run the <code>mmd-xslt</code> utility from the command line &#8212; run it from within its bin/ directory when you do. This script transforms the XHTML file into one that includes a ToC at the top. In my drive towards a successful transformation, I realized that if I had a well-formed XML document, then surely there were commands in PHP that would allow me to gain a reference to the <code>BODY</code> node, and inject it and its inner XML into the WordPress Page output. Sure enough, the necessary functions exist. I did however go back to scratch with the template files. I created a dupe of page.php and content-page.php (doc.php and content-doc.php respectively), and modified the content-doc.php thusly:</p>

<pre class="crayon-plain-tag">&lt;code&gt;&amp;lt;article id=&quot;post-&amp;lt;?php the_ID(); ?&amp;gt;&quot; &amp;lt;?php post_class(); ?&amp;gt;&amp;gt;
    &amp;lt;header class=&quot;page-header&quot;&amp;gt;
        &amp;lt;?php
        $title = get_the_title();

        $docs_path = get_post_meta(get_the_ID(), 'docs_path', true);
        if(file_exists($docs_path)) {
            libxml_use_internal_errors(true);
            $xml = simplexml_load_file($docs_path);
            foreach (libxml_get_errors() as $error) {
                error_log($error-&amp;gt;message);
            }
            if($xml)
                $title = $xml-&amp;gt;head-&amp;gt;title;
        }

        printf('&amp;lt;h1 class=&quot;entry-title&quot;&amp;gt;%s&amp;lt;/h1&amp;gt;', $title);
        ?&amp;gt;
    &amp;lt;/header&amp;gt;&amp;lt;!-- .entry-header --&amp;gt;

    &amp;lt;div class=&quot;entry-content clearfix&quot;&amp;gt;
        &amp;lt;?php
        if($xml) {
            _e($xml-&amp;gt;body-&amp;gt;asXml());
        } else {
            the_content( __( 'Continue reading &amp;lt;span class=&quot;meta-nav&quot;&amp;gt;&amp;amp;rarr;&amp;lt;/span&amp;gt;', 'the-bootstrap' ) );
        }
        the_bootstrap_link_pages(); ?&amp;gt;
    &amp;lt;/div&amp;gt;&amp;lt;!-- .entry-content --&amp;gt;
    &amp;lt;?php edit_post_link( __( 'Edit', 'the-bootstrap' ), '&amp;lt;footer class=&quot;entry-meta&quot;&amp;gt;&amp;lt;span class=&quot;edit-link label&quot;&amp;gt;', '&amp;lt;/span&amp;gt;&amp;lt;/footer&amp;gt;' ); ?&amp;gt;
&amp;lt;/article&amp;gt;&amp;lt;!-- #post-&amp;lt;?php the_ID(); ?&amp;gt; --&amp;gt;
&lt;/code&gt;</pre>

<p>Please take note of the use of <code>libxml_use_internal_errors(true);</code>. I&#8217;m keeping the page from showing error in the output. IMHO, it&#8217;s a security issue if you expose internal paths to the outside world. Now, back to bending MMD 3 and Scrivener to match my particular requirements. Thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/au-contraire-mon-frere-or-putting-the-x-in-xhtml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Necessity Is The Mother of Invention or: Updating a WordPress Page From a Sparse-Checkout of a Git Repo</title>
		<link>http://www.codenoevil.com/necessity-is-the-mother-of-invention-or-updating-a-wordpress-page-from-a-sparse-checkout-of-a-git-repo/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=necessity-is-the-mother-of-invention-or-updating-a-wordpress-page-from-a-sparse-checkout-of-a-git-repo</link>
		<comments>http://www.codenoevil.com/necessity-is-the-mother-of-invention-or-updating-a-wordpress-page-from-a-sparse-checkout-of-a-git-repo/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 15:08:52 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>

		<guid isPermaLink="false">http://www.analogousmember.com/?p=557</guid>
		<description><![CDATA[Learning I&#8217;ve been working on this app spec for weeks at work. In an effort to improve on what I&#8217;d accomplished, I reached out to my friend, and one of the smartest people I know, Peter Becan. I wanted him to teach me how to do it right. Peter&#8217;s been doing this sort of thing&#8230; <a href="http://www.codenoevil.com/necessity-is-the-mother-of-invention-or-updating-a-wordpress-page-from-a-sparse-checkout-of-a-git-repo/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h3>Learning</h3>

<p>I&#8217;ve been working on this app spec for weeks at work. In an effort to improve on what I&#8217;d accomplished, I reached out to my friend, and one of the smartest people I know, <a href="http://tro.pe/J3s4Gx">Peter Becan</a>. I wanted him to teach me how to do it right. Peter&#8217;s been doing this sort of thing for a lot longer than I have, and has a particular knack for it. Learning to correctly prepare an application specification is harder than learning to program, IMHO.</p>

<p>As my spec writing progressed, I&#8217;d email Peter PDF output from <a href="http://www.scrivener.com">Scrivener</a> as I accumulate enough new content worthy of a dispatch. <a href="http://tro.pe/J3tZuB">marked</a>, which I&#8217;m using to preview <a href="http://tro.pe/IpLy7O">MultiMarkdown</a> markup in my Scrivener document, generates the formatted PDFs. I realize that as time progresses, keeping Peter in the loop requires a different method. In order to keep him informed, and not have to email him a new PDF every so often, I needed to make use of the web to post the formatted output.</p>

<h3>Scrivener</h3>

<p>Scrivener supports outputting HTML generated by the MultiMarkdown processor as a <code>Compile For</code> target. There are instructions on how to use MultiMarkdown with Scrivener <a href="http://tro.pe/JiKzv1">here</a>, however the instruction appear out of date. I&#8217;m using Scrivener 2.2 and some of the preferences mentioned in the instruction have either moved, or no longer exist. Luckily, by setting options using MultiMarkdown metadata and a simple change in the compile settings, I obtained the necessary output.</p>

<blockquote>
  <p>For posterity&#8217;s sake, what I did not find was <code>MultiMarkdown Settings…</code> under the <code>File</code> menu</p>
</blockquote>

<p>Two things are necessary to produce the desired output for inclusion in a WordPress page. First, as mentioned in the instructions, I had to enable the exporting of Titles for both Documents and Groups within Scrivener. You do this by checking the check box under Title in the Formatting options of the Compilation Settings sheet.</p>

<p><a href="http://eight.cdn-codenoevil.com/wp-content/uploads/2012/04/Screen-Shot-2012-04-22-at-10.51.png"><img src="http://six.cdn-codenoevil.com/wp-content/uploads/2012/04/Screen-Shot-2012-04-22-at-10.51-300x203.png" alt="" title="Screen-Shot-2012-04-22-at-10.51" width="300" height="203" class="alignnone size-medium wp-image-700" /></a></p>

<p>Second, I opted to use a <code>Meta-Data</code> file at the <em>very top</em> of my Scrivener doc to coerce the MultiMarkdown processor to produce the necessary output. The metadata fields that I use are:</p>

<pre class="crayon-plain-tag">&lt;code&gt;Title:  Contractor Spec   
Format: snippet  
&lt;/code&gt;</pre>

<p>The key is the <code>Format</code> field. What that does is instruct the MultiMarkdown processor to only create the HTML for the given markup and <em>not</em> an entire XHTML page. Clearly if I am including the output in a WordPress page, only the HTML associated with the MultiMarkdown markup is necessary; the cruft associated with a well-formed XHTML page (i.e. <code>HEAD</code>, <code>BODY</code>, etc.) would be in the way. With all the correct metadata and settings in place, I use Compile&#8230; with a Compile For of <code>MultiMarkdown -&gt; HTML</code> and save that in its own subfolder within my source tree.</p>

<h3>Git</h3>

<p>Git. Love it or hate it, it&#8217;s the linchpin in the operation. My Git repo resides on the same server as my WordPress installation. Having that scenario started me thinking about how I would get the HTML snippet residing within the repo into a place that I could serve <em>just</em> that content and not the entire source tree. I started Googling <code>update website with git</code>, and sure enough I found what I was looking for. After sifting through several top results, I found that <a href="http://tro.pe/HZit45">this</a> was the best answer.</p>

<blockquote>
  <p>I have an addendum to those instructions. For the remote path, I used a <code>file://</code> path pointing to the path of the real repo on the server. Found that <a href="http://tro.pe/HZlEsP">here</a>.</p>
</blockquote>

<p>The key to copying the HTML to a place I can include it from is using a <code>post-receive</code> hook in Git. Very simply put:</p>

<blockquote>
  <p>The post-receive hook runs after the entire process is completed and can be used to update other services or notify users. (taken from <a href="http://tro.pe/HZiN2U">Pro Git</a>)</p>
</blockquote>

<p>However, if you follow the steps set out in the instructions, you&#8217;ll wind up with your <em>entire</em> repo in the web directory. While that may work in most cases, it was not ideal for what I was trying to do. Next pass at Google had me looking for ways to only checkout a subset of the entire repo. The key to that is something entitled a <code>sparse checkout</code>. I used the steps outlined <a href="http://tro.pe/HZjQQi">here</a> to only checkout the folder (and it&#8217;s content) that contained the HTML snippet. One exception however about the sparse checkout instructions, you will need to include a &#8216;*&#8217; at the end of the path. Otherwise you will receive from Git:</p>

<blockquote>
  <p>error: Sparse checkout leaves no entry on working directory</p>
</blockquote>

<p>For my &#8220;local&#8221; repo on the server, I picked a spot outside of the root of the WordPress installation to checkout the files to.</p>

<h3>WordPress</h3>

<p>Last step in the process. How do I insert a snippet of HTML that resides on disk into a WordPress page? Create your own page template and use a custom field. In the end, this was rather easy, once I learned how to do it. This <a href="http://tro.pe/HZmd5K">page</a> at the WordPress codex explains how to create the custom template and where to upload it to your server. Scroll down a bit till you get to the <strong>Using Custom Fields</strong> section. For this, I&#8217;m using a custom field called <code>doc_path</code>. Here is my custom template named <code>docs.php</code>:</p>

<pre class="crayon-plain-tag">&lt;code&gt;&amp;lt;?php
/*
 Template Name: docs
 */
if (is_page() ) {
$docs_path = get_post_meta($posts[0]-&amp;gt;ID, 'docs_path', true);
}
get_header();?&amp;gt;

        &amp;lt;div id=&quot;primary&quot; class=&quot;span8&quot;&amp;gt;
            &amp;lt;div id=&quot;content&quot; role=&quot;main&quot;&amp;gt;
                &amp;lt;?php include($docs_path); ?&amp;gt;
            &amp;lt;/div&amp;gt;&amp;lt;!-- #content --&amp;gt;
        &amp;lt;/div&amp;gt;&amp;lt;!-- #primary --&amp;gt;

&amp;lt;?php
get_sidebar();
get_footer();
?&amp;gt;
&lt;/code&gt;</pre>

<p>This allows me to specify the full path to the HTML snippet on disk that I want included in the WordPress page.</p>

<p><a href="http://eight.cdn-codenoevil.com/wp-content/uploads/2012/04/Screen-Shot-2012-04-23-at-12.01.png"><img src="http://eight.cdn-codenoevil.com/wp-content/uploads/2012/04/Screen-Shot-2012-04-23-at-12.01-1024x115.png" alt="" title="Screen-Shot-2012-04-23-at-12.01" width="770" height="86" class="alignnone size-large wp-image-701" /></a></p>

<p>Make sure, as I forgot this the first time I saved my new Page, to set the template for the Page to your custom template like this:</p>

<p><a href="http://seven.cdn-codenoevil.com/wp-content/uploads/2012/04/Screen-Shot-2012-04-23-at-12.13.png"><img src="http://eight.cdn-codenoevil.com/wp-content/uploads/2012/04/Screen-Shot-2012-04-23-at-12.13-283x300.png" alt="" title="Screen-Shot-2012-04-23-at-12.13" width="283" height="300" class="alignnone size-medium wp-image-702" /></a></p>

<h3>Final Output</h3>

<p>Because the application I&#8217;m writing the spec for is proprietary, I can&#8217;t share the real fruits of my labor with you. However, what I did do is create <em>another</em> page containing a snippet of <code>sample.html</code> from the MultiMarkdown <a href="http://tro.pe/HZoJJj">source</a> at github. My sample page is <a href="http://tro.pe/HZoONa">here</a>. <em>P.S.</em> Yes, I am aware that the sample page has a broken image link.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/necessity-is-the-mother-of-invention-or-updating-a-wordpress-page-from-a-sparse-checkout-of-a-git-repo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Import PDF into Visio 2007</title>
		<link>http://www.codenoevil.com/import-pdf-into/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=import-pdf-into</link>
		<comments>http://www.codenoevil.com/import-pdf-into/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 16:03:40 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>
		<category><![CDATA[Computer-aided design]]></category>
		<category><![CDATA[Data Formats]]></category>
		<category><![CDATA[Document]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Microsoft Visio]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Publishing]]></category>
		<category><![CDATA[snagit]]></category>
		<category><![CDATA[visio]]></category>

		<guid isPermaLink="false">http://wp.analogousmember.com/?p=514</guid>
		<description><![CDATA[I had a need to import some CAD drawings into my Visio document. The CAD drawings were provided to me as PDF documents. Visio has no native way to insert a PDF into a drawing. SnagIt to the rescue. Besides being an excellent app for making screenshots, it installs itself as a printer. Well, all&#8230; <a href="http://www.codenoevil.com/import-pdf-into/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I had a need to import some CAD drawings into my Visio document.  The CAD drawings were provided to me as PDF documents.  Visio has no native way to insert a PDF into a drawing.  <a href="http://www.techsmith.com/screen-capture.asp">SnagIt</a> to the rescue.  Besides being an excellent app for making screenshots, it installs itself as a printer.  Well, all I did was print my PDF to the SnagIt printer, saved the image as a TIFF, and then inserted the TIFF into my Visio drawing.</p>
<p>The resolution was quite good and I achieved exactly what I wanted.  Gotta love it when shits works out!</p>
<div class="zemanta-pixie" style="margin-top:10px;height:15px"><a class="zemanta-pixie-a" href="http://www.zemanta.com/" title="Enhanced by Zemanta"><img class="zemanta-pixie-img" src="http://img.zemanta.com/zemified_e.png?x-id=180a3ecb-e086-493c-bfb2-9938ed686dcf" alt="Enhanced by Zemanta" style="border:none;float:right" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/import-pdf-into/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SqlCeReplication PublisherSecurityMode</title>
		<link>http://www.codenoevil.com/sqlcereplicatio/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sqlcereplicatio</link>
		<comments>http://www.codenoevil.com/sqlcereplicatio/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 10:58:21 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>

		<guid isPermaLink="false">http://wp.analogousmember.com/?p=513</guid>
		<description><![CDATA[I&#8217;ve been toying around with SQL Server CE replication. For whatever reason, my code was failing with the following exception when I called Synchronize(): Failure to connect to sql server with provided connection information. sql server does not exist, access is denied because the iis user is not a valid user on the sql server,&#8230; <a href="http://www.codenoevil.com/sqlcereplicatio/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been toying around with SQL Server CE replication.  For whatever reason, my code was failing with the following exception when I called Synchronize():</p>
<blockquote><p>
Failure to connect to sql server with provided connection information. sql server does not exist, access is denied because the iis user is not a valid user on the sql server, or the password is incorrect.
</p></blockquote>
<p>As it turns out, if you use the follow form of the SqlCeReplication ctor (as observed using Reflector):</p>
<blockquote><p>
public SqlCeReplication(string internetUrl, string internetLogin, string internetPassword, string publisher, string publisherDatabase, string publication, string subscriber, string subscriberConnectionString)
</p></blockquote>
<p>the PublisherSecurityMode is set to SecurityType.NTAuthentication.  Otherwise, if you use the parameterless ctor, PublisherSecurityMode is left to its default, which is SecurityType.DBAuthentication.  This assignment is NOT documented.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/sqlcereplicatio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What Is The Right Foreground For a Given Background</title>
		<link>http://www.codenoevil.com/what-is-the-rig/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=what-is-the-rig</link>
		<comments>http://www.codenoevil.com/what-is-the-rig/#comments</comments>
		<pubDate>Mon, 11 May 2009 17:18:35 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>

		<guid isPermaLink="false">http://wp.analogousmember.com/?p=510</guid>
		<description><![CDATA[I am working on a SQL Server 2005 Reporting Services (SSRS) report that has differing row colors based on a value in each data row.  The color value is defined in the database.  When I initially created the report, each row had a variable background color but the foreground color was black.  The first time&#8230; <a href="http://www.codenoevil.com/what-is-the-rig/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I am working on a SQL Server 2005 Reporting Services (SSRS) report that has differing row colors based on a value in each data row.  The color value is defined in the database.  When I initially created the report, each row had a variable background color but the foreground color was black.  The first time I ran the report, my dark blue background didn&#8217;t contrast well with my black foreground.  I quickly realized that I needed a way to vary the foreground color programmatically based on the background color.  After first discussing things over with <a href="http://twitter.com/twisty7867">Nate</a>, here is the expression I came up with for the Color property of the table row:</p>

<pre class="crayon-plain-tag">&lt;code&gt;=IIF(
((
((CInt(Fields!Status_Color.Value) And &amp;amp;HFF) * 299) +
((CInt(Fields!Status_Color.Value) &amp;lt;&amp;lt; 8 And &amp;amp;HFF) * 587) +
((CInt(Fields!Status_Color.Value) &amp;lt;&amp;lt; 16) * 114)
) / 1000) &amp;amp;lt; 125,
&quot;White&quot;,
&quot;Black&quot;
)
&lt;/code&gt;</pre>

<p>Let me explain where this all comes from.  First off, the color that is stored in the database is used by a VB6 program.  VB6 stores colors as BGR and .NET stores colors as RGB (well, technically aRGB).  The first step is to break down the value from the database to its constituent parts (red, green, and blue) using bitshift operations I learned from <a href="http://www.bit-101.com/blog/?p=1054">Keith Peters</a> and then apply the contrast formula I found from <a href="http://tools.cactusflower.org/analyzer/">Colin Lieberman</a>&#8216;s website. I then determine that if the blackground is a dark color, then we use white and for a light background, black.  This appears to working like a charm.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/what-is-the-rig/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Request Tracker RT_SiteConfig.pm</title>
		<link>http://www.codenoevil.com/request-tracker/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=request-tracker</link>
		<comments>http://www.codenoevil.com/request-tracker/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 23:09:53 +0000</pubDate>
		<dc:creator>David B. Bitton</dc:creator>
				<category><![CDATA[über-geek]]></category>

		<guid isPermaLink="false">http://wp.analogousmember.com/?p=508</guid>
		<description><![CDATA[Don&#8217;t forget when you update the RT_SiteConfig.pm file, you need to restart httpd. I was banging my head against the wall of this one until I had a moment of clarity.]]></description>
				<content:encoded><![CDATA[<p>Don&#8217;t forget when you update the RT_SiteConfig.pm file, you need to restart httpd.  I was banging my head against the wall of this one until I had a moment of clarity.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codenoevil.com/request-tracker/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced
Database Caching 7/23 queries in 0.046 seconds using disk
Object Caching 1014/1061 objects using disk
Content Delivery Network via Amazon Web Services: CloudFront: five.cdn-codenoevil.com

 Served from: www.codenoevil.com @ 2013-05-24 02:03:05 by W3 Total Cache -->