How to display content from other website using your own simple Drupal 7 module

From time to time I went with Drupal into situations where I need to display a block populated with content coming from another website. Parsing other website’s RSS or using the Aggregator module is not always possible nor comfortable.  So own custom module could be a solution. Here is how I did this job.

I will show you simple module with Drupal 7 syntax, but you can rewrite it to the Drupal 6 in a very similar way. You will only need another syntax for creating the blocks. The block content generation is similar in Drupal 6 and Drupal 7.

This example module generates the block with latest ten articles coming from another Drupal installation. As there is database calling showed, you can rewrite this module to get the data from other CMS. I use this trick to get the data from four Drupal websites and one Wordpress installation and show the results as five same styling blocks. The user doesn’t notice any differences.

How to prepare other database connection

At first, you have to edit your settings.php file and provide a connection string for other database. Go to the sites/default folder and edit the settings.php. Search for this part:

    $databases['default']['default'] = array(

      'driver' => 'mysql',

      'database' => 'databasename',

      'username' => 'username',

      'password' => 'password',

      'host' => 'localhost',

      'prefix' => '',

    );

Select it, copy to the clipboard and paste the copied text just after this part. Now edit the pasted code, so you will rewrite the first ‘default’ word to the name of the other database you want to work with:

   $databases['borrowed']['default'] = array(                                   

     'driver' => 'mysql',                                                       

     'database' => 'otherdatabasename',                                            

     'username' => 'username',                                            

     'password' => 'password',                                                 

     'host' => 'localhost',                                                    

     'prefix' => '',                                                           

   );  

Save the changed settings.php and double check that the new version has been saved. The settings.php file could be blocked from rewrite, so in this case, use the FTP client to change the permissions, rewrite it and then change the permissions again.

Drupal 7 module structure

Now you can start to write your own custom module. Go to the sites/all/modules folder and create a new folder with the name of your module, I will name it as ‘borrowcontent’ in this article. After that create two files:

  • modulename.info
  • modulename.module

For this example I created files named borrowcontent.info and borrowcontent.module. Now you have to tell Drupal a few information about the new module. Open your *.info file and provide the information this way:

name = BorrowContent

description = Sample module to show how to borrow content from other database

package = Development

core = 7.x

files[] = borrowcontent.module

My example has five parts, each on its own row:

  • name – the name of the module
  • description – short info about the module, it will be shown in the module list administration part
  • package – this defines a group which displays the module in the module’s list
  • core – here you have to define the Drupal core version which is this module written for
  • files[] – using this syntax you have to provide a list of all code files which belongs to your module

The *.module file needs to have the <?php characters on its beginning. Now you are ready to provide the module’s functionality.

How to create block in Drupal 7 module

My example module will create a block with links to ten latest articles coming from another website. So we will use two functions which tells Drupal about the block availability and about its content:

The links above point to the api.drupal.org so you can check what these functions can do in their max. For using these functions in your own module you have to rename them. Replace the word hook with the machine name of your module (the name of the *.module file).

The hook_block_info() tells Drupal about your block. This function returns the array with information about all blocks provided by your module. I will return only one item in the $blocks[] array. If you need more blocks, copy the part with the $block[] syntax, rewrite its content and you will have second block.

function borrowcontent_block_info() {

  $blocks['other_website_latest'] = array(

    'info' => t('Latest articles borrowed from other website'),

    'cache' => DRUPAL_NO_CACHE

  );

  return $blocks;

}

The $block['block_machine_name'] consists of an array with one item at least. I used two items within it:

  • info – here you provide string with description for the block_machine_name block.
  • cache – I do not want to cache this block’s content so I used this row to tell Drupal about that

Now there is a time to provide a function that is needed for blocks viewing. Drupal will call it every time the block should be displayed. Again, replace the word hook from the hook_block_view() with the machine name of your module.

function borrowcontent_block_view($delta = '') {

  $block = array();

  switch ($delta) {

    case 'other_website_latest':

      $block['subject'] = t('Latest articles borrowed from other website');

      $block['content'] = borrowcontent_other_website_latest();

      break;

  }

  return $block;

}

This function gets the delta identifier of the module which is going to be displayed. So I use the switch operator and the case syntax to serve the displaying of my only block called other_website_lastest. This delta name has to be specified in the hook_block_info(), check it above. You have to provide the subject of this block (could be rewritten by user using Drupal block administration part) and the content of this block. I provide its content via another function within my module.

Of course, if you specified more the one module within your hook_block_info() specification, you will still use only one hook_block_view() function. The difference will be that the switch will work with more case syntaxes.

How to display data from other website within a block on Drupal 7 website

So now you have this done:

  • connection string to the other database in settings.php file
  • module’s folder
  • *.info and *.module files
  • module’s specification inside the *.info file
  • implementations of hook_block_info() and hook_block_view() functions

Now you are ready for the latest part of our example module. Check the function name you have provided as the $block[‘content’] generator above. Create this function within your *.module file. Here is my example:

function borrowcontent_other_website_latest()

  db_set_active('borrowed');

  $query = "SELECT nid, title FROM {node} WHERE type = 'story' AND status = 1 ORDER BY created DESC LIMIT 0,10";

  $result = db_query($query); 

  $return = '<ul>';

  foreach ($result as $record) {

    $base = 'http:// www.otherwebsiteurl.com /';

    $relative = drupal_get_path_alias('node/'.$record->nid);

    $return .= '<li>'.l($record->title, $base.$relative, array('title'=>$record->title)).'</li>'

  }

  $return .= '</ul>'

  db_set_active('default');

  return $return;

}

Now a few words about how this function works and what is it doing. First, very important calling – db_set_active(). This function gets only one parameter – it is a name of the connection strings for the other database. If you forget check the part describing the changes inside the settings.php, which I mentioned above. What you have to know and probably shouldn’t forget is that as soon as you call the db_set_active() all database operations are performed against the other database, not into your Drupal installation. So be extremely care and be sure to call the db_set_active('default') as soon as you don’t need to work with other database. Calling the db_set_active('default') brings you back to the Drupal. Once again, do not forget to call it.

Now you can provide a string, which will select the data from the database. It is a simple SQL SELECT query. I work here with another Drupal installation. The table name could be inside the {} brackets so the Drupal will replace it with appropriate prefixes when configured in the connection string. I call here for nids and titles of ten latest nodes of the type story. I am also interested only in published content (status = 1).

Now I call db_query() to get the result from my query strings. I will display the data as HTML unordered list so I start preparing the output string with <ul> mark.

Now the most important part. Using the foreach statement I browse all rows from the query results and create a link for the articles selected. Because the Drupal API’s l() function doesn’t work with absolute paths by default I will need three rows of code (another reason is I would like to be cleared for you).

I put the base URL of the other website into the $base variable. From the query I have nid for each node selected. So I use the drupal_get_path_alias() to get relative node’s URL(). On the third row inside the foreach statement I use the Drupal’s l() function the provide a link (<a> mark). The parameters are the linked string (the name of the node from other website), the path of the link and array with attributes where I provide the title=”” attribute for the <a></a>.

After the foreach statement I provide the end of the unordered list and call the db_set_active('default'). At the end I return the string with unordered list and links prepared above.

Improvement using DBTNG

Drupal 7 has nice improvement for database related tasks. It is called DBTNG and stands for Database layer: The Next Generation. So if you prefer to create a string with SQL query, feel free to use the code above. To be completely on Drupal 7 way I will show you one alternative of the code above. It will looks like this:

function borrowcontent_other_website_latest()

  db_set_active('borrowed'); 

  $select = db_select('node', 'n')

  ->fields('n', array('nid','title'))

  ->condition('n.type','story')

  ->condition('n.status',1)

  ->orderBy('n.created','DESC')

  ->range(0,10); 

$nodes = $select->execute()->fetchAll();

  if (!empty($nodes)) {

     $return = '<ul>';

    foreach ($nodes as $node) {

       $base = 'http:// www.otherwebsiteurl.com /';

       $relative = drupal_get_path_alias('node/'.$node->nid);    

       $return .= '<li>'.l($node->title, $base.$relative, array('title'=>$node->title)).'</li>';

}

    $return .= '</ul>';

  } 

  db_set_active('default');

  return $return;

}

Its structure is very similar to the previous one. There are still the db_set_active() callings and the foreach statement to browse the results and provide the list of links. But the SQL query string has been gone. There is a new syntax:

  $select = db_select('node', 'n')

  ->fields('n', array('nid','title'))

  ->condition('n.type','story')

  ->condition('n.status',1)

  ->orderBy('n.created','DESC')

  ->range(0,10); 

I have to say, when I see the DBTNG syntax at first I didn’t understand it. But now, after few months working with it I like it. I seems to be easier then creating the query strings. And there is another reason for using it – it is database independent so the Drupal will create the SQL query/command compatible with its all supported database engines.

How it works: There is a db_select() function where I select the table and name it as n (not exactly needed in this article but you will need it when working with JOINs for example). After that I select the fields from the working table n, which I am interested in – the nid and the title.

There are two conditions which stands for the WHERE part of the SQL query string. At first I select only the results where the type is story and the status is 1 (published nodes). Then I provided the orderBy clause and the range, which has the same functionality as the LIMIT in the SQL query string.

Using the $select->execute()->fetchAll() I will get the objects with rows selected from the database. You can also call $select->execute()->fetchAll(PDO::FETCH_ASSOC) to get the results as the arrays.

Example Drupal 7 module download

So I hope you will find this example useful. I provided package with complete module from this article. There are both variants of the borrowcontent_other_website_latest() function – one is commented. I also provide some tips to the comments inside the code.

You can use the Devel module and it’s dsm() function to display the array or object content using Krumo tool, you can also work with complete node’s data. All you need is to call node_load($nid) and you will get the complete node object including its body.

Related fles