Labs
Replicating the official Twitter widget feed with native Drupal
In this post I will be going over how to recreate the official Twitter profile widget with Drupal, there are a two mains reasons why you would want to do this.
First and foremost is performance. By using the core Aggregator module we move the loading of tweets from browser-side on every page load (which impacts on page load time) via JavaScript to Drupal cron run. This does mean that you might want to increase your cron run frequency depending on how often you expect the Twitter feed to be updated (Aggregator module will check every 15 minutes at the most).
Second is to remove an external dependency on the Twitter assets, if Twitter were to go down the missing JavaScript for the widget which can cause the page load to block as well as the tweets will obviously be missing. Aggregator effectively caches the Twitter output, removing the external dependencies.
Notes:
- There will be points where you need to enter the desired twitter username this will be in code as “REPLACE_WITH_USERNAME”, there is also one occurrence of “REPLACE_WITH_REAL_NAME”.
- You can download a zip file of the views templates, css and template.php functions here: http://labs.deeson.net/twitter-widget/deeson-labs_twitter_files.zip.
So let’s get started!
- Make sure you’ve got the Views and core Aggregator modules installed and enabled.
- Create your Twitter aggregator feed, navigate to: Content management > Feed aggregator > Add feed.
- Give your new feed a relevant title e.g. “Site Twitter feed”, to get the URL of your Twitter feed navigate to your Twitter page e.g. http://twitter.com/timdeeson, then in the right sidebar you should see a link for “RSS feed of x’s tweets”, simply copy this URL, then click Save.
- Return to the feed listing by navigating to: Content management > Feed aggregator. You should see your new feed, but also that it has 0 items, on the same row click “update items” to retrieve your tweets.
- You should see a message stating there were updates for your new feed, now you should take note of what your Twitter aggregator feed ID is, you can find this out by taking a look at the edit URL, which will be admin/content/aggregator/edit/feed/X, with X being the feed ID.
- Now that we’ve got the feed setup and some of your tweets imported, we’ll now create the view that will display them, so navigate to: Site building > Views > Add. Give the new view a name, e.g. “twitter_feed” and fill in the other details making sure to select the “View type” “Aggregator item”, click Next.
- Start by adding a new filter “Aggregator feed: Feed ID”, the operator should be “is equal to” and enter your feed ID you found in step 5.
- Add a new sort criteria “Aggregator: Timestamp” Descending.
- Add the following fields “Aggregator: Body”, “Aggregator: Timestamp” and “Aggregator: Link” - All fields should not have a label.
- Click on the “Aggregator: Timestamp” field to edit it, under “Date format” select “Time ago (with “ago” appended)”, and then in the “Custom date format” field enter the number “1”. This will produce our tweet age e.g. “15 hours ago”, or “2 days ago”.
- Click on the “Aggregator: Link” field to edit it, uncheck “Display as link”.
- Next add a block display.
- Save the view.
-
Add the following code to your themes template.php file:
The first function filters text to turn replies and hashtags into links, and the second function is a general cleanup function for the tweet text which removes the username (which is always at the start of each feed item), changes all URLs into links, and finally executes the first function.
/** * phptemplate_twitter_link_filter(). * Code borrowed from the contributed Twitter module * http://drupal.org/project/twitter * * This helper function converts Twitter-style @usernames * and #hashtags into actual links. * * Modified with link classes */ function phptemplate_twitter_link_filter($text, $prefix = '@', $destination = 'http://twitter.com/') { $class = $prefix == '@' ? 'twtr-atreply' : 'twtr-hashtag' ; $matches = array( '/\>' . $prefix . '([a-z0-9_]{0,15})/i', '/^' . $prefix . '([a-z0-9_]{0,15})/i', '/(\s+)' . $prefix . '([a-z0-9_]{0,15})/i', ); $replacements = array( '><a href="' . $destination . '${1}" class="'. $class .'">' . $prefix . '${1}</a>', '<a href="' . $destination . '${1}" class="'. $class .'">' . $prefix . '${1}</a>', '${1}<a href="' . $destination . '${2}" class="'. $class .'">' . $prefix . '${2}</a>', ); return preg_replace($matches, $replacements, $text); } /** * phptemplate_twitter_transform_content(). * Helper function to transform links, * usernames and hashtags into proper HTML */ function phptemplate_twitter_transform_content($tweet) { // remove username $tweet = preg_replace("/^([a-zA-Z0-9-_]*): /", '', $tweet, 1); // turn normal urls into links $tweet = preg_replace("/(http:\/\/|(www\.))(([^\s<\"]{4,68})[^\s<\"]*)/", '<a href="http://$2$3" rel="nofollow" class="twtr-hyperlink">$2$4</a>', $tweet); // change usernames into links $tweet = phptemplate_twitter_link_filter($tweet); // change hash tags into links $tweet = phptemplate_twitter_link_filter($tweet, '#', 'http://twitter.com/search?q='); return $tweet; }
- Return to your view, once editing select the block display.
- Under “Basic settings” click on “Theme: Information”, we now want to make a view template for “Row style output”, in our case we won’t be using this view for anything else, so I’ve chosen “views-view-fields--twitter-feed.tpl.php” but choose the filename you require (bear in mind that having a different view name will effect the template filenames). Create this file within your theme folder.
-
Inside your new view template insert the following code:
This code will replicate the markup of the Twitter profile widget. Note that you should replace occurences of REPLACE_WITH_USERNAME with your twitter username.
<?php // $Id$ /** * @file views-view-fields.tpl.php */ $tweet_url_parts = array_reverse(explode('/', $fields['link']->content)); $tweet_id = $tweet_url_parts[0]; ?> <div id="tweet-id-<?php print $row->id + 1; ?>" class="twtr-tweet"> <div class="twtr-tweet-wrap"> <div class="twtr-tweet-text"> <p> <?php print phptemplate_twitter_transform_content($fields['description']->content); ?> <i> <?php print l(strip_tags($fields['timestamp']->content), $fields['link']->content, array('attributes' => array('class' => 'twtr-timestamp'))); ?> <?php print l('reply', "http://twitter.com/?status=@REPLACE_WITH_USERNAME&in_reply_to_status_id=$tweet_id&in_reply_to=REPLACE_WITH_USERNAME", array('attributes' => array('class' => 'twtr-reply'))); ?> </i> </p> </div> </div> </div>
-
Next we'll add a template for the “Style output” with the filename “views-view-unformatted--twitter-feed.tpl.php” (or as you require) and add the following code:
This simplifies the output so we don't get any wrapper elements (which can cause some trouble with the stock twitter CSS).
<?php // $Id$ /** * @file views-view-unformatted--twitter-feed.tpl.php * * @ingroup views_templates */ foreach ($rows as $id => $row) { print $row; }
- Now for the final overall view template, create the file “views-view--twitter-feed.tpl.php” (or as always, with your required filename) in your theme folder with the following code:
The above code will allow us to add the twitter widget header and footer code via the view header/footer features.
<?php // $Id$ /** * @file views-view--twitter-feed.tpl.php * * @ingroup views_templates */ ?> <div class="<?php print $classes; ?> twtr-widget twtr-widget-profile"> <div class="twtr-doc"> <?php if ($admin_links): ?> <div class="views-admin-links views-hide"> <?php print $admin_links; ?> </div> <?php endif; ?> <?php if ($header): ?> <div class="view-header twtr-hd"> <?php print $header; ?> </div> <?php endif; ?> <?php if ($exposed): ?> <div class="view-filters"> <?php print $exposed; ?> </div> <?php endif; ?> <?php if ($attachment_before): ?> <div class="attachment attachment-before"> <?php print $attachment_before; ?> </div> <?php endif; ?> <?php if ($rows): ?> <div class="view-content twtr-bd"> <div class="twtr-timeline"> <div class="twtr-tweets"> <?php print $rows; ?> </div> </div> </div> <?php elseif ($empty): ?> <div class="view-empty"> <?php print $empty; ?> </div> <?php endif; ?> <?php if ($pager): ?> <?php print $pager; ?> <?php endif; ?> <?php if ($attachment_after): ?> <div class="attachment attachment-after"> <?php print $attachment_after; ?> </div> <?php endif; ?> <?php if ($more): ?> <?php print $more; ?> <?php endif; ?> <?php if ($footer): ?> <div class="view-footer twtr-ft"> <div> <?php print $footer; ?> </div> </div> <?php endif; ?> <?php if ($feed_icon): ?> <div class="feed-icon"> <?php print $feed_icon; ?> </div> <?php endif; ?> </div> </div>
- Now (providing you still have the view theming options open), click “Back to theming information” to go back to the view template filename variant listing, after the list you should see a button which says “Rescan template files”. Click on the button to make sure Drupal picks up on our new template files. Once you have done that click “OK”
-
At this point you can add in the optional widget header and footer should you want to, if you want to add the header then under “Basic settings” click on “Header” and enter the following code:
You will want to replace instances of REPLACE_WITH_USERNAME with your twitter username, also you will need to find the location of your avatar and replace REPLACE_WITH_AVATAR_URL, you can do this by going to widget generation page https://twitter.com/goodies/widget_profile and entering your twitter username, click on “Test Settings”, then you can firebug Inspect element the image to get the URL.
<div class="twtr-hd"> <a class="twtr-profile-img-anchor" href="http://twitter.com/REPLACE_WITH_USERNAME" target="_blank"> <img alt="profile" class="twtr-profile-img" src="REPLACE_WITH_AVATAR_URL" /> </a> <h3> REPLACE_WITH_REAL_NAME </h3> <h4> <a href="http://twitter.com/REPLACE_WITH_USERNAME" target="_blank">REPLACE_WITH_USERNAME</a> </h4> </div>
- Make sure the input format is “Full HTML” and then click Update.
-
You can also add in the optional footer code via the same method in the view footer, simply follow the same method as with the header, but with the following code:
As usual, you'll need to replace REPLACE_WITH_USERNAME with your twitter username.
<div> <a href="http://twitter.com" target="_blank"> <img alt="" height="15" src="http://widgets.twimg.com/j/1/twitter_logo_s.png" /> </a> <span> <a class="twtr-join-conv" href="http://twitter.com/REPLACE_WITH_USERNAME" target="_blank">Join the conversation</a> </span> </div>
- Save the view! Nearly there :)
- When the Twitter widget is embedded it includes it's own base stylesheet and also the settings you specify when you embed your widget, you will need to add this code to your theme, you can use the CSS included in the zip file mentioned at the start of the article and edit the settings colours to match your theme and copy this code to your theme css file.
- With the CSS in place, all you need to do is place the block generated by our new view in a region, and that's it!
If you've got any questions or improvements on anything mentioned in this article please comment below!
Comments
hello great article... I have some request, it nice to have a demo page or something screen-shot because it have a lot of step hard to test.
Add new comment