Category Archives: Programming

Middleman Dynamic Content in Single Template

I’ve been playing a little with middleman (http://middlemanapp.com/) to build some simple static sites lately and have been looking at how to do this a little more dynamically.

More precisely, I wanted to be able to deliver unique content or yml data files to the same html.erb template file. For my use case I was attempting to get multiple slightly different versions of the same page, same layout but variations on the same content. Rather than recreating every page over again I just wanted to allow a writer to be able to copy paste the yml file and update it. Turns out it’s pretty simple.

The example I’ll go through is to have three pages for 3 people (Bob, Joe & Linda). But instead of creating a 1 to 1 relationship between the yml and html.erb files:

data/bob.yml => source/bob.html.erb
data/joe.yml => source/joe.html.erb
data/linda.yml => source/linda.html.erb

I’ll have 3 yml files and 1 html.erb file:

data/bob.yml, data/joe.yml, data/linda.yml, source/person.html.erb

What this will allow me to do is 2 simple things: 1. I can more easily add additional people, just copy the yml file and update their content. 2. use a single template (not layout) for all of those people without having to update each of them.

Here are the 3 sets of files needed for the example, you can do this with any fresh middleman app that you have just initialized.

config.rb

["bob", "joe", "linda"].each do |person|
    proxy "/#{person}.html", "/person.html", :locals => { :person => person }, :ignore => true
end

This will configure the proxy to route each of your people to the template. The first line is effectively whitelisting which urls of people will be passed to my template. The second line then has 4 arguments passed to the proxy.

  1. “/#{person}.html” – this is the url to proxy, the #{person} is replaced with the names you listed in the first line
  2. “/person.html” – this is the template file found in the source directory that will render each of your pages
  3. :locals => { :person => person } – create a variable called person with the above persons name in it, you can use this to uniquely access the data for each person
  4. :ignore => true – ensure that person.html isn’t a page of its own

source/person.html.erb

Name: <%= data.people[person].name %>
<br/>
Age: <%= data.people[person].age %>

A very simple template file that will output our data for each person. You can see that we are using the person variable name to get the content dynamically. This will load the data/people/bob.yml file or the data/people/linda.yml for example.

data/people/bob.yml

name: Bob
age: 36

Finally, our data file for bob, you can copy paste this into as many different people as necessary.

View my full example on GitHub (https://github.com/wesdeboer/middleman-example)

Vagrant Symlink Error

I had a problem getting symlinks to work with Vagrant but lets get symlinks setup first before I get to the problem. First thing to do which is well documented is you need to add the following line to your Vagrantfile:

config.vm.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/WebDocRoot", "1"]

The problem most people have is that this line relates to your share_folder config value. See the following:

config.vm.share_folder "WebDocRoot", "/var/www", "www"

The share_folder config option has 3 initial params (identifier, guest path, host path). The customize option must relate to the identifier, look at the WebDocRoot value in those two options.

The problem is that I received the following error:

The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

mkdir -p /vagrant/www

So let’s look at the error, I can’t make the directory /vagrant/www, it’s returning an error.

vagrant ssh
ls -l /vagrant

In my case I could see that /vagrant/www already existed and was a dead symlink that pointed to a non-existant directory. Wait a minute it links to a directory on my host machine not my guest machine. Why is that?

The /vagrant directory in the guest is an automatically generated share_folder by Vagrant and it maps to the current directory your Vagrantfile is located in. I had put a symlink in this directory on my host machine and that symlink was then available in the guest as it’s parent was a share_folder already. Thus when I tried to create a new share_folder at the path /vagrant/www it failed as it already existed as a symlink.

Simple enough don’t create a share_folder there, create it elsewhere inside the guest machine. I moved it from /vagrant/www/ to /var/www/ as outlined above and problem solved.

Use curl to upload files and post other data

This should’ve been more obvious to me but it did take a few minutes of playing around and reading the manual to get this right. I wanted to post data to a api using curl and one of the items was a file upload and another was a simple field/value.

To upload a file via curl:

curl -X POST -F "image=@profile.jpg" http://api.example.com/profile

In php this will give you the profile.jpg in the $_FILES[‘image’], now to add additional field values you just add additional -F arguments like this:

curl -X POST -F "image=@profile.jpg" -F "phone=1234567890" http://api.example.com/profile

Upgrade WordPress Install to Use SVN Externals

I recently wrote a post about setting up a new wordpress site using svn externals to include the wordpress core and optionally themes/plugins with a fresh svn repository. I’m now going through previously setup sites and changing them over to this new structure and thought it would be worth a quick post to take note of the steps I took to complete that.

Prerequisites:

  • a svn repo with wordpress installed in the trunk
  • a checked out working copy and you are currently inside this dir
  1. Let’s start by adding the wordpress core as an external to the root of our current working copy
    svn pe svn:externals .

    Enter in the following:

    wordpress http://svn.automattic.com/wordpress/tags/3.1.2

    Then:

    svn up

    You’ll now have a wordpress dir with the core of wordpress.

  2. With a new wordpress core we don’t need the original base of wordpress that we had so let’s remove the php files in root as well as the includes and admin folders. You need to keep your wp-content folder as that’s where all the custom wordpress stuff goes. You also need to keep your wp-config.php and the .htaccess (as well as any other non-wordpress files that you may have stored here).
    svn rm wp-admin wp-includes index.php wp-activate.php wp-app.php wp-atom.php wp-blog-header.php wp-comments-post.php wp-commentsrss2.php wp-config-sample.php wp-cron.php wp-feed.php wp-links-opml.php wp-load.php wp-login.php wp-mail.php wp-pass.php wp-rdf.php wp-register.php wp-rss.php wp-rss2.php wp-settings.php wp-signup.php wp-trackback.php xmlrpc.php
    svn commit -m 'remove original wordpress files and add core via externals to ./wordpress'
  3. Now we just need to modify the config and htaccess to handle the new structure and we have the base done.
    vi wp-config.php

    Be sure the following is included (after the WP_HOME is defined, I always make sure I define my WP_HOME and WP_SITEURL just to be sure it’s correct when I move from dev to staging to production):

    define('WP_CONTENT_URL', WP_HOME.'/wp-content');
    define('WP_CONTENT_DIR', realpath(ABSPATH.'../wp-content'));
    vi .htaccess

    Replace this piece in the .htaccess:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]

    With the below content:

    RewriteCond %{REQUEST_URI} ^/wp-(.*)(.php) [OR]
    RewriteCond %{REQUEST_URI} ^/wp-includes [OR]
    RewriteCond %{REQUEST_URI} ^/wp-admin
    RewriteRule ^(.*)$ /wordpress/$1 [L]
    RewriteCond %{REQUEST_URI} !^/wordpress/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /wordpress/index.php
    RewriteRule ^(/)?$ wordpress/index.php [L]
  4. If you have any standard plugins you can replace them with the svn repo that is provided by wordpress via externals as well (if they exist). I’ll use wptouch as my example:
    svn rm wp-content/plugins/wptouch
    svn pe svn:externals wp-content/plugins
    wptouch http://plugins.svn.wordpress.org/wptouch/tags/1.9.29/
    svn commit -m 'replace wptouch plugin with a svn external copy tagged 1.9.29
    svn up

    This will only work with plugins that have svn repositories, such as ones available in the wordpress plugins repo or a third party provided repo. I’d recommend sticking with a tagged version and just changing the tag to the newest version as you see fit. If you prefer to stay on the bleeding edge you can easily use the trunk. The one thing to note about using the trunk is that you do need to run a ‘svn update’ in order to get the latest version from the trunk, it’s not pushed to you, so you are still in control.

WordPress with SVN Externals

I’ve read through a number of articles about using svn externals to setup a wordpress install and none of them were quite accurate or worked as written for myself (probably due to most being written previous to wordpress 3.0 but I haven’t verified and don’t wish to do so). I thought it was a good idea to log my instructions so that I could easily replicate it and if anyone else has troubles perhaps this will help you out.

Prerequisites:

  1. you have a clean svn repository to start with
  2. you are working from the root of your websites docroot
  3. you are comfortable with wordpress and svn already
  4. wordpress 3.1.3 is the latest release, we’ll initially start working with 3.1.2 to show the ease of upgrade to 3.1.3
  1. Checkout your repository into a working copy:
    svn co https://svn.example.com/example/trunk example
  2. Enter your working copy and setup the wordpress core via externals
    cd example
    svn pe svn:externals .

    Then enter the following and save:

    wordpress http://svn.automattic.com/wordpress/tags/3.1.2
  3. You can do an update and you’ll receive the wordpress core
    svn up
  4. Lets create our themes/plugins/uploads directories
    mkdir -p wp-content/themes wp-content/plugins wp-content/uploads
    svn add wp-content
  5. With the themes directory now created and added we can add some themes, lets get the twentyeleven theme and the delicate theme.
    svn pe svn:externals wp-content/themes

    Then enter the following and save:

    twentyeleven http://core.svn.wordpress.org/tags/3.1.2/wp-content/themes/twentyten
    delicate http://themes.svn.wordpress.org/delicate/3.4.3
    svn ci -m 'add base directories'
    svn up
  6. You will now see you have your wordpress core and a theme checked out from wordpress 3.1.2, next step is to setup the wordpress config. Copy the base wordpress config file, config the database connections and add additional content to setup for the new directory structure.
    cp wordpress/wp-config-sample.php wp-config.php
    vi wp-config.php

    Enter the following anywhere before the “/* That’s all, stop editing! Happy blogging. */” line and be sure to set all the other db settings etc as necessary:

    define('WP_HOME', 'http://example.com');
    define('WP_SITEURL', WP_HOME);
    define('WP_CONTENT_URL', WP_HOME.'/wp-content');
    define('WP_CONTENT_DIR', realpath(ABSPATH.'../wp-content'));
  7. Next up is the .htaccess file, create one and enter the following contents:
  8. # BEGIN WordPress
    
            RewriteEngine On
            RewriteBase /
            RewriteCond %{REQUEST_URI} ^/wp-(.*)(.php) [OR]
            RewriteCond %{REQUEST_URI} ^/wp-includes [OR]
            RewriteCond %{REQUEST_URI} ^/wp-admin
            RewriteRule ^(.*)$ /wordpress/$1 [L]
            RewriteCond %{REQUEST_URI} !^/wordpress/
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteRule ^(.*)$ /wordpress/index.php
            RewriteRule ^(/)?$ wordpress/index.php [L]
    
    # END WordPress
  9. You can now visit your site, fill in the details and complete the online install as normal. You will have to re-activate (or choose another) theme as the path to the default theme isn’t accurate because of the base install, so choose the delicate theme or any other theme of your choice in order to see the homepage after install.
  10. Now the magic of running this through svn externals is that you can update the core or any themes plugins with a couple quick commands. For example to update the wordpress core to 3.1.3 you just have to change the externals value and do a svn up and you’re done like below:
    svn pe svn:externals .

    Then update the current entry to the following:

    wordpress http://svn.automattic.com/wordpress/tags/3.1.3

    And then do an update

    svn up

All of this can be applied to the plugins/themes at anytime for adding and updating which makes things really fast and easy. It’s great in an environment where you work with a team and have developed some internal plugins or themes that you like to reuse you can link in any common required plugins and all your sites receive the updates together, no more merging in changes to separate projects.