Development environments done right, with Vagrant, Puppet and VirtualBox

vagrant_structure

When I first started out in web development, I worked directly on the server. I had an FTP client and I’d download files, edit them, and re-upload them. If it was a “serious” project, I might even use source control. I thought this was a pretty handy way to work… Looking back on that workflow, I’m embarrassed, but the thing is, I know people who still work that way. I’m not going to go into the merits of having a dedicated development environment, automated builds and tests, etc… Just take it as a given that you need them. With that being said, however, it’s always a pain trying to set up a new development environment, and having an environment already set up on my laptop doesn’t guarantee that it’ll be the same environment that the next client has in production. If you’re on a different machine, it’s a problem. I’m going to talk about how I’ve solved this age old problem using Vagrant, Puppet and VirtualBox.

Continue Reading…

Moving Kohana to a non public directory

Kohana, PHP framework

This is the second post in my series on the Kohana php framework.  For more, see:

Part 1: Getting started with the Kohana php framework

One of the simplest, and most basic security precautions that you can take is to move your application’s files into a non-public area of your webhost. Having your applications code and configs sitting there in your document root is just never a good idea. An attacker could very easily gain access to the source code of your application, as well as configuration. Next thing you know, there’s empty beer cans all over your apartment and the silverware’s missing. In general, this applies to any kind of web based application, but I’m going to be dealing specifically with Kohana, as part of my series on Getting Started with Kohana.

Continue Reading…

More Cascading AJAX Dropdowns with CodeIgniter

ci_logo

Probably the most popular post in the history of this blog is “Populate DropDowns with jQuery and Codeigniter”. In that post, I gave a quick overview of how to set up a dropdown or select box that depends on the value selected in another form element. That post was never really intended to be a complete “How To”, but it’s been such a popular post that I wanted to revisit the idea, and write up a more complete discussion of this technique.

What I’m going to do here is to create and populate an HTML select element using values that are dependent on a selection in another HTML input. In this case, I’m using two select elements, but you could adapt the technique for any kind of input. For example, let’s say you have a form that displays data for a zip code. Now, there are a LOT of zip codes in the US, and you probably don’t want to make your users scroll through such a long list to choose the value they’re interested in. So, you add another HTML select element that allows the user to choose the specific state that contains the zip code. So, initially, the zip code select element is blank, or set to some default value. Then once the user chooses a state, the zip code element is populated with all of the zip codes for that state. Nice, huh?

Continue Reading…

Convert a Drupal Multi-site Installation to a Single Site.

drupal_clones

One of Drupal’s more interesting abilities is the “Multi-site” installation.  Drupal allows you to run multiple, separate websites with different users and different content, all on one single installation of Drupal.  At first, this sounds exciting, because it has the potential to simplify site maintenance and updates.  You only have to install a module once, and share it across all of your sites, etc…  Like everything else in the web development world, this method has its proponents and its detractors.  I’m not going to discuss the pros and cons of Drupal’s multi-site installation right now.  However, I’ve recently decided to switch AutoRemarketing.com from a multi-site to a stand alone.

AR.com is the biggest site I’ve ever worked with.  It’s a trade publication for the Used Car industry.  It gets updated with new content several times a day, and it gets, on average, 130,000 page views every month.  I inherited the site, and it had been set up initially as a multi-site, along with several other sites.  So, trying to move the installation, without breaking anything, and without interrupting traffic would be challenging to say the least.

In the end, I was able to move everything over, with no loss of functionality, although I did have to take the site down for about 10 minutes.  Here’s the procedure that I followed.  First & foremost, I made backups of absolutely everything, then I made sure that I had multiple copies of the backups (I’m a little paranoid!).  I also made sure to install drush, the Drupal shell.  You can read more about drush at their site, but let me just say that it’s an amazing tool, and it’s utterly indispensable for serious Drupal work.

Once I had everything backed up and ensured that Drush was installed, my next step was to create drush aliases for everything.  I simply added the following code to ~/.drush/aliases.drushrc.php:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$aliases['ar_dev'] = array(
    'uri' => 'ar.sacherokeedev.com',
    'root' => '/var/www/html/ar.sacherokeedev.com',
    'db-url' => 'mysql://dbuser:dbpassword@localhost/database',
);
 
$aliases['ar_prod'] = array(
    'uri' => 'autoremarketing.com',
    'root' => '/var/www/html/drupal_media',
    'db-url' => 'mysql://dbuser:dbpassword@localhost/database',
);

I then used drush’s rsync capabilities to copy everything from the multi-site to the new location with this simple command:

1
drush rsync @ar_prod @ar_dev

The one gotcha in this case, is that drush rsyncs the entire directory, which means that you get a complete copy including all of the multi-site files.  There’s probably a way to tell drush to only sync certain files, but I just copied everything then deleted what I didn’t need.  The next thing to worry about is that multi-site & standalone installations use different file paths, so images won’t show up, until you run the following MySQL commands (either via phpMyAdmin or command line or your MySQL tool of choice:

 

1
UPDATE files SET filepath = REPLACE(filepath, 'autoremarketing', 'default') WHERE filepath LIKE '%autoremarketing%';
1
UPDATE boxes SET body = REPLACE(body, 'autoremarketing.com', 'default') WHERE body LIKE '%sites/autoremarketing.com%';

The first command changes the file path for all of the files in your database, the second changes the path to any images that are contained in Drupal blocks.  That’s essentially it, but I also ran the following drush commands just to make sure:

1
drush updb
1
drush cc

Finally, I had to log back into the site as admin, and reset the favicon and logo paths at admin/build/themes/settings.  Once that was done, all is well, and I now have a stand alone installation instead of a multi-site.

 

A Better Approach to WordPress Portfolios

blue-l

This idea was directly taken from John Watson’s excellent post, Building a better WordPress portfolio.  I’ve taken his concept, and I think, improved upon it slightly.  Thanks John.

I’m always looking for a better way to display my portfolio of various projects.  I’ve tried hand-coded pages, WordPress pages, custom WP functions that pull all the posts from a special category, etc…  and I just never have been able to come up with something that I really like.

See how meta I can be?!

Enter John Watson’s post about using WordPress Custom Post Types (CPT).  Custom post Types were, technically, introduced in WP 2.9, although there was no way to work with them in the user interface until 3.0.  Basically, they are WP’s answer to Drupal’s Custom Content Kit (CCK).  You know about Pages and Posts.  Well, Custom Post Types let you define additional “things”, so that you might have Pages, Posts, Teapots, and Projects.  The basic idea is that you define a Custom Post Type in functions.php, which gives you an entry in the WP admin sidebar to manage those entities.  In this instance, I’ve created a Custom Post Type of “Projects”, so that I can now add, edit and manage my portfolio, directly in the admin area.

The first step is to create the CPT in your themes functions.php.  The function that you need is register_post_type(), which you can read about in the Codex.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
add_action('init', 'techno_init');
function techno_init() {
  register_post_type('project',
    array(
      'labels' => array(
      'name' => __('Projects'),
      'singular_name' => __('Project'),
      'add_new_item' => __('Add New Project'),
      'edit_item' => __('Edit Project'),
      'new_item' => __('New Project'),
      'view_item' => __('View Project'),
      'search_items' => __('Search Projects'),
    ),
    'public' => true,
    'exclude_from_search' => true,
    'has_archive' => true,
    'menu_position' => 5,
    'supports' => array(
    'title', 'editor', 'excerpt','thumbnail', 'custom-fields', 'revisions'
    )
  )
 );
}

Technically, that’s all that you need to do.  However, one thing I wanted, was the ability to have snippets from each project displayed on a parent “Projects” page.

Themeing the output

It turns out, that this is very easily done.  You simply need to add a file to your theme, in this case, titled “archive-project.php”.  That keys the WP theme system to use that file in order to display a listing of all of your custom post types.  You can also create a custom template to display single project pages, by creating a new file, again directly in your theme directory.  This file should be titled “single-project.php”.  Again, that title causes the WP template heirarchy to choose the file to display your post.

Finally, you may get a 404 page not found error when you first try to load the Projects page.  To fix that, go to Settings->Permalinks in order to rebuild the permalink structure.  You don’t have to make any changes, just visit the Permalinks page, and click Save.  You now have a “Projects” parent page, themed by “archive-project.php”.  In my case, each individual Project page is still being themed by “single.php”.