---
title: "Latin Grammys Graduation"
url: "/articles/latin-grammys-graduation"
type: article
date: 2012-10-23
updated: 2014-05-12
---

# Latin Grammys Graduation

#  Latin Grammys Graduation 

 A case study in re-platforming latingrammy.com

 By

 [  Jerad Bitner   ](/about/jerad-bitner) 

 October 23, 2012

  

## Requirements

The previous version of the site was built on Ruby on Rails in a custom content management system that allowed administrators of the site to have content types, categories, and even translations. This was all stored in a MySQL database with a simple schema that allowed for a pretty easy migration into Drupal.

The task was to re-create the entire site within Drupal, keeping the exact same content types, content, and existing design with the exception of a new homepage, new header and new footer. The new homepage design is based off of the current [Grammy.com](https://www.grammy.com/)'s homepage design.

**Previous Homepage**: ![old](https://evernote.com/skitch)

**Newest Homepage**: ![new](https://evernote.com/skitch)

The Recording Academy wanted to re-platform this on Drupal for a couple of reasons. The first is that since Grammy.com is on Drupal 6 and will be upgraded to Drupal 7 before the next annual awards show, we could leverage some of the work in building the Latin Grammys website with Drupal 7 for the upgrade of Grammy.com itself. The second reason was to bring the site more inline with Grammy.com in terms of capabilities in content editing, advertising, and future enhancements to the site could be leveraged from any improvements that end up being made on Grammy.com.

## Migration

For the migration work on this project, we decided to create a custom drush command that could run the various migration scripts. The scripts are split out by content type: each script migrating the pertinent information for a particular content type. They are comprised of a simple function that runs bootstrapped Drupal code to take data from the old Ruby database and transform it for the new Drupal database.

You can find the code for this custom drush command, `$ drush lmi` in [this gist](https://gist.github.com/82e48a3749d55d1dcaa6).

We then have one simple bash script that runs drush commands in succession, like so:

  ```

# Clean install using our installation profile written with profiler.
drush site-install lagra -y
drush upwd admin --password="admin"
drush fra --force -y
drush dis overlay -y
drush cc all

# Migrate taxonomy terms.
drush lmi tag
drush lmi genre
drush lmi award

# Migrate content.
drush lmi event
drush lmi nominee
drush lmi page
drush lmi photo
drush lmi podcast
drush lmi press_release
drush lmi sponsor
drush lmi video import
  
```

You may also notice that within that bash script, we are installing Drupal from scratch with a custom install profile called 'lagra'. This installation profile is using [Profiler](http://drupal.org/project/profiler/) and does some simple enabling of core modules, contrib modules, custom features, and sets a few initial variables within the variables table. If you haven't looked into using Profiler on your projects, you should. It allows you to do some pretty complex operations with very simple syntax right in your profile's `.info` file.

You can find the code for this custom install profile in [this gist](https://gist.github.com/17ff5c4216367abaf26f).

What this all leads to is a relatively simple and quite an efficient way to completely reinstall the entire project from scratch at any given point. All of the features of the site are in custom [Features](http://drupal.org/project/features) modules, and the migration scripts run automatically, so a fresh install of the project is as easy as running `$ ./docroot/scripts/reset.sh` at any given time. We found this led to a very rewarding workflow during the entire duration of the project.

## Translation

Another huge requirement for the site (in fact, one we underestimated) was the use of three different languages on the site: English, Spanish, and Portuguese. For this we had to add a whole slew of `i18n_*` modules. Here's the list:

- Internationalization (i18n)
- Block languages (i18n\_block)
- Menu translation (i18n\_menu)
- Multilingual content (i18n\_node)
- Path translation (i18n\_path)
- String translation (i18n\_string)
- Taxonomy translation (i18n\_taxonomy)
- Translation sets (i18n\_translation)
- Variable translation (i18n\_variable)
- Views translation (i18nviews)
- I18n page views (i18n\_page\_views)

### Challenges

The old Ruby system had a very competent system for managing translations of content. However, not all content in the system was translated, and so there were some challenges in making sure that we could switch to a different language and not have the page show up empty simply because the content was not translated for that particular views listing. The listing being empty was not ideal from a user's standpoint, nor from a content editor's standpoint. So we opted to do a little extra work in the migration scripts for the particular content types that did not have translations. We simply created the English version of the nodes, and at the same time used the same copy for the translations. This resulted in populated views for each language, and an ideal way for content editors to browse the listings and quickly know what content needed to be translated, hit an edit button, and then translate.

Another challenge we didn't account for was all of the strings that are not translated automatically. The String translation module was easy enough to use for most cases, but for the times we found it lacking, we ended up using the [String Overrides](http://drupal.org/project/stringoverrides) module to fill in the gaps.

We also found that keeping string translations in code was problematic. We opted for using the `$conf` array like so:

  ```php

global $conf;
$conf['locale_custom_strings_es'][''] = array(
  "You must be logged in to access this page." => "Debes estar registrado para acceder a esta pÃ¡gina.",
);
  
```

However, this also became an issue once we decided to start using the String Overrides module because the `$conf` array would simply override any translations we would put in the String Overrides UI. So, we opted to use this `$conf` array method to get the values into the database initially (hitting save in the String Overrides UI) and then just remove the `$conf` array. Then, we could use the UI to translate the few strings that remained.

This is still something we haven't solved, so if you have any suggestions on easily keeping string translations in code (Ã la Features), we would love to know about it in the comments!

## Involvement

The following were involved in this project at various stages and in various roles:

*In order of code contributions.*

![brockboland](https://www.lullabot.com/sites/default/files/imagecache/93x93/images/entry/smile-fence.JPG)

**Brock Boland: *Developer at Lullabot***

---

![sirkitree](https://www.lullabot.com/sites/default/files/imagecache/93x93/picture-22_0.jpg)

**Jerad Bitner: *Senior Developer &amp; Technical Project Organizer at Lullabot***

---

![davexoxide](https://www.lullabot.com/sites/default/files/imagecache/93x93/picture-21_4.jpg)

**David Burns: *Senior Developer at Lullabot***

---

![makangus](https://www.lullabot.com/sites/default/files/imagecache/93x93/images/entry/mugshot.jpg)

**Angus Mak: *Developer at Lullabot***

---

![blc](https://www.lullabot.com/sites/default/files/imagecache/93x93/images/entry/IMG_1780-cropped.JPG)

**Ben Chavet: *Systems Administrator at Lullabot***

---

![Bao_Truong](https://secure.gravatar.com/avatar/47720ff0bfbb1275ff536bb16cf08bc6?d=http%3A%2F%2Frapportive-proxy.heroku.com%2Fproxy%3Furl%3Dhttp%253A%252F%252Fmedia.linkedin.com%252Fmpr%252Fmpr%252Fp%252F1%252F000%252F07d%252F0cc%252F29d7fcc.jpg&amp;s=80)

**Bao Truong: *Software/Web Developer at The Recording Academy***

 Published in:

- [  Drupal Development   ](/topics/drupal-development)
- [  Drupal Site Building   ](/topics/drupal-site-building)

 

   You must have JavaScript enabled to use this form.

## Get in touch with us

### Tell us about your project. We'd love to hear from you!

 First Name  

 Last Name  

 Your email address  

 Your organization  

 How you heard about us  

 Tell us more 

     Leave this field blank