vih.dk now in Drupal 7

4 minutters læsning

Previously vih.dk was programmed in a home grown CMS system. The system had some limitations regarding adding and editing new regular pages, so we needed a new system which could handle that easily. With the release of Drupal 7, we found a perfect fit.

Version control. We wanted the site in version control and created with an install profile, and we chose github.com for our code, as we have no secrets. We split up our code in three distinct repositories:

  • Deploy. drush .make and install profile
  • Modules and features. Her we exported features and made our own custom modules
  • Theme

We used our drush .make and .build file to pull in everyhing automatically, and building the site is as easy as:

drush make vih_dk.build ~/workspace/vih_dk_buildAnd if we want to update the site automatically, we simply run the following command from the directory of our install profile (and navigates to update.php afterwards).

drush make --no-core --contrib-destination=. vih_dk.make You can see our entire deploy script at github.com.

Porting the theme. First we started to port our theme to Drupal 7. It took a little time to get accustomed to the new syntax, but it was ported in a little more than a day. We made the decision to make some things a little more simple, to make the transition to Drupal easier. We needed different background and props depending on the content on the page. We are still building that part.

Exposing tables for views

We had no time to move all the old functionality to the new site. We were hoping that we could just implement the legacy application written in konstrukt as a custom module. However, there are some problems, so we ended up putting the legacy parts on a subdomain and just made link to that. To make the integration as seamless as possible, we chose to expose some of the legacy tables to views, so we could easily create the links to the relevant parts of the old application. It was easy after reading the following article about exposing database fields for views.

Migrating data

We tried a couple of different things to migrate the data, but ended up using the brilliant migrate module. We mostly needed to migrate text, and all it took was about 20 lines of code to import our old news. The documentation is still a little scarce, but the project comes with decent examples.

Here is what I ended up with:

<pre type="php"><?php
class MigrateNews extends Migration {
  public function __construct() {
    parent::__construct();
    $this->description = t('Migrate news from legacy database');
    $this->team = array(
      new MigrateTeamMember('Lars Olesen', 'lars@vih.dk', t('Webmaster')),
    );
    $query = db_select('nyhed', 'nyhed', array('target' => 'vih'))
             ->fields('nyhed', array('id', 'overskrift', 'tekst', 'date_created', 'date_updated', 'published'))
             ->where('nyhed.active = :active', array(':active' => 1));
    /*
$query->leftJoin('keyword_x_object', 'kxo', 'nyhed.id = kxo.belong_to');
$query->innerJoin('keyword', 'keyword', 'keyword.id = kxo.keyword_id');
// Gives a single comma-separated list of related terms
$query->addExpression('GROUP_CONCAT(keyword.keyword)', 'terms');
*/
    $this->source = new MigrateSourceSQL($query);
    $this->source->setMapJoinable(false);
    $this->destination = new MigrateDestinationNode('story', array('text_format' => 'full_html'));
    $this->map = new MigrateSQLMap($this->machineName,
        array(
          'id' => array('type' => 'int',
                        'unsigned' => TRUE,
                        'not null' => TRUE,
                       )
        ),
        MigrateDestinationNode::getKeySchema()
      );
    $this->addFieldMapping('title', 'overskrift');
    $this->addFieldMapping('body', 'tekst');
    $this->addFieldMapping('uid')
         ->defaultValue(1);
    $this->addFieldMapping('created', 'date_created');
    $this->addFieldMapping('changed', 'date_updated');
    $this->addFieldMapping('status', 'published');
    //$this->addFieldMapping('field_tags', 'terms')->separator(',');
  }
}

I was struggling with a couple of issues, but had very kind help from the developers of the module. You gotta love the Drupal community.

1) Use other database. The legacy data was in another database from the new Drupal database. It is fairly easy in Drupal to use another target for the database (make sure you have setup the secondary target in your settings.php. This following code makes sure that the other database is queried.

<span class="nv">$query</span> <span class="o">=</span> <span class="nx">db_select</span><span class="p">(</span><span class="s1">'nyhed'</span><span class="p">,</span> <span class="s1">'nyhed'</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'target'</span> <span class="o">=></span> <span class="s1">'vih'</span><span class="p">));</span>Migrate will automatically think that all tables are in the same database. To use the secondary target in the migrate code, you have to do the following:

<span class="nv"><span style="display: none;"> </span>$this</span><span class="o">-></span><span class="na">source</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MigrateSourceSQL</span><span class="p">(</span><span class="nv">$query</span><span class="p">);</span>
<span class="nv">$this</span><span class="o">-></span><span class="na">source</span><span class="o">-></span><span class="na">setMapJoinable</span><span class="p">(</span><span class="k">false</span><span class="p">);</span>

2) Import with special filter. On the legacy site the data was in saved in HTML. That means we need to get it into the Drupal nodes with the “Full HTML” text format. That was easily solved by:

<span class="nv">$this</span><span class="o">-></span><span class="na">destination</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MigrateDestinationNode</span><span class="p">(</span><span class="s1">'story'</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'text_format'</span> <span class="o">=></span> <span class="s1">'full_html'</span><span class="p">));</span>I could not figure out, how to construct the query with the taxonomy, so it only imports the content of the old rows into a node. But that can easily be achieved by:

<span style="display: none;"> </span>drush cc all
drush migrate-import MigrateNews<span style="display: none;"> </span>

And during testing it is easily to roll back the updates by:

drush migrate-rollback MigrateNewsCustom modules with configuration options

We had a legacy newsletter integration with an old system, which we also had to keep. In about an hour we ported it to a Drupal module with a backend where we could save the needed configuration settings needed for the newsletter supplier. We were looking in a couple of ressourced I forgot, but you can see the entire code for the custom module at github.com.

Kommentarer

Chad

Great read. Taxonomy isn’t easy to learn, but it’s actually easier than ‘destination node’. Check out beer.inc and wine.inc in the migrate_examples folder inside the migrate module.

Skriv en kommentar

Din e-mail bliver ikke offentliggjort. Obligatoriske felter er markeret *

Indlæser...