Thursday, September 5, 2013

How to create slideshows with embedded YouTube videos in Drupal 7

 Thanks to views_slideshow module it’s a very easy task to implement. Sometimes slideshows contain embedded YouTube videos. And thanks to the great Media module, it is not a very hard task to do either.
The only problem we face is when the user clicks play – the slideshow still switches to the next slide. This article addresses this problem.
We have found a nice example of reacting on YouTube player play / pause.
In order to use this example we will need to override media-youtube-video template as we will need to change the output.
In order to accomplish this we can create our own template and add it to suggestions in case this field is displayed in a view with slideshow.
/**
* Implements hook_theme().
*/
function mymodule_theme() {
return array(
'mymodule_media_youtube_video' => array(
'variables' => array('uri' => NULL, 'options' => array()),
'template' => 'mymodule-media-youtube-video',
),
);
}

/**
* Preprocess function for template media-youtube-video.tpl.php
*/
function mymodule_preprocess_media_youtube_video(&$variables) {
if (!_mymodule_search_backtrace('template_preprocess_views_view_field')) {
return;
}

$views_id = drupal_static('mymodule_preprocess_views_view_field');
if (empty($views_id)) {
return;
}

drupal_add_js('http://www.youtube.com/player_api');
drupal_add_js(drupal_get_path('module', 'mymodule') . '/mymodule.js');

$variables['theme_hook_suggestions'] = array('mymodule_media_youtube_video');

$variables['iframe_id'] = 'media-youtube-' . $variables['id'];
$variables['views_id'] = $views_id;
}
?> 

The mymodule_preprocess_media_youtube_video() function does some tricks:
1. It checks whether rendering of media file is done inside the view. For this we check the backtrace for template_preprocess_views_view_field function. This is pretty hacky but I haven't found a nicer way to check. It is needed so we do not modify output if for example media file displayed in the node.
2. It loads $views_id from static variable. This is another pretty ugly hack, but it is needed for passing a variable to javascript (so we know what slideshow to pause / start). Also when we prepare that variable we check if a view actually uses slideshow style.
I would love to hear if you know a better workaround for these two hacks. Write in the comment form below or on our social profiles: TwitterFacebook.
The function where we prepare the view id:
/**
* Preprocess function for views-view-field.tpl.php.
*
* Statically cache view information to pass to mymodule.js so we know what slideshow to pause.
*/
function mymodule_preprocess_views_view_field(&$variables) {
$views_slideshow_id = &drupal_static(__FUNCTION__);
$views_slideshow_id = '';

$view = $variables['view'];
if ($view->style_plugin->plugin_name == 'slideshow') {
$views_slideshow_id = $view->name . '-' . $view->current_display;
}
}
?> 

Now the template file:

As you can see, we are passing iframe_id, video_id and views_id as attributes of the iframe so javascript can use them.
And the last piece is the javascript itself:

(function ($) {
Drupal.behaviors.mymodule = {
attach: function (context) {
$('.media-youtube-mymodule').once('mymodule').load(function() {
iframe_id = $(this).data('iframe_id');
video_id = $(this).data('video_id');
views_id = $(this).data('views_id');

// Example of interacting with YouTube API's
//@link http://jsfiddle.net/masiha/4mEDR/
var mymodule_player = new YT.Player(iframe_id, {
videoId: video_id,
events: {
'onStateChange': function (event) {
if (event.data == YT.PlayerState.PLAYING) {
Drupal.viewsSlideshow.action({
"action": 'pause',
"slideshowID": views_id,
"force": true
});
}
else if (event.data == YT.PlayerState.PAUSED) {
Drupal.viewsSlideshow.action({
"action": 'play',
"slideshowID": views_id,
"force": true
});
}
}
}
});
});
}
};
})(jQuery); 

The full code of this drupal module can be downloaded here.
Now, after enabling this module, if you build a slideshow with media youtube files it should apply this functionality automatically.
Enjoy.

Friday, August 30, 2013

How to Build Multilingual Drupal Sites

There are many different languages available for a Drupal installation, but what if you want to have a site with more than one language? Drupal is up to the task, but it's not a trivial procedure. There are two areas that need translation.
First, you'll need to translate the interface, which includes the button texts, drop down menus, messages and other languages you use to interact with the site. Customizing the interface is fairly simple, and there are language files you can download that will help you make short work of it. Drupal developers often refer to this as localization.
Second, you'll need to translate the content. There are some modules that will make this possible, but this does require more effort than translating the interface.
Let's take a look at how you can translate the interface and the content.

Step 1: Download and install all the necessary modules

These are the basic modules you must have to make the translation work. Download and install and enable all of these modules before moving on.

Step 2: Enable and configure Locale

tutuploadsStep_2__Enable_and_configure_Locale.png
This is a native module and will be found in the core section of the module page.
tutuploadsmedia_1326858686932.png
Start by making sure that the Locale and Localization Update modules are installed and enabled. Localization Update is added when you install the Entity Translation module.

Step 3: Configure Languages

tutuploadsStep_3_Configure_Languages.png
Go to Configuration and scroll down to the Regional and Language section. You will see two new options: Languages and Translate interface. Click Languages.
tutuploadsmedia_1326857306494.png
On the Languages page, click Add Language.
tutuploadsmedia_1326857397128.png
In the PREDEFINED LANGUAGE section, choose a language from the drop down menu. If you don't find the language you want, you can define your own language. That's beyond the scope of this tutorial. You can find downloads of contributed languages on this site http://localize.drupal.org.
Add all the desired languages and then save the configuration by scrolling to the bottom of the screen.

Step 4: Choose a detection method and enable it

tutuploadsStep_4__Choose_a_detection_method_and_enable_it_with_a_ch.png
Check the box next to the method you want to use. Scroll to the bottom to Save Configuration.
Warning: do not disable or change the default language. This will cause serious problems and unexpected results. Your default language doesn't have to be English. If you used one of the international versions of Drupal, leave whatever default language you started with.

Step 5: Configure Translation Updates

tutuploadsStep_5_Configure_Translation_Updates..png
From the Translation Updates tab you can configure automated updates for your language files.
tutuploadsmedia_1326860356104.png
Go to Configuration, then in the Regional and Language section, click on the other option you just added "Translate Interface" (see Step 3 if you forgot where it is). Here you will see various tabs that allow you to import, update and manage the interface strings.
tutuploadsmedia_1326860773347.png
The language file you installed will do the most common translations for you. Using the tools on this page, you can search for and find any string (line of text) you want to translate.
In the image above I searched for the string "An AJAX HTTP error occurred." The string must be entered exactly as it is shown on the site. Click edit to start translating the string.
tutuploadsmedia_1326860938401.png
You can now add the text in the various languages so that the string will be translated for those languages. If you don't enter a translation, the string will still be visible to the user, but only in the default language.

Step 6: Add the translation to the website

tutuploadsStep_6_Add_the_translation_to_the_website.png
Enable the following modules if you haven't already done so.
  • Entity Translation
  • Title
  • Internationalization
  • Entity API
  • Variable
After enabling these, go to Structure, then Content types.
tutuploadsmedia_1326922982363.png
Click edit on the content type you wish to work with.
tutuploadsmedia_1326923055299.png
Click Publishing options and enable Multilingual support.
  • If enabled, a language selection field will be added to the editing form, allowing you to select from one of the enabled languages.
  • You can also turn on translation for this content type, which lets you have content translated to any of the installed languages.
  • If disabled, new posts are saved with the default language. Existing content will not be affected by changing this option.
  • If entity translation is enabled, it will be possible to provide a different version of the same content for each available language.
tutuploadsmedia_1326923446012.png
Click Multilingual settings. Choose your extended language options and support. Click Save content type. Repeat this for each content type you have on your site.

Step 7: Make each field translatable

tutuploadsStep_7_Make_each_field_translatable.png
Go back to the content type you are editing and click on manage fields. You will now see the Title on the manage fields tab has an option to replace it. Click replace.
tutuploadsmedia_1326924079411.png
If you check Replace title with a field instance, the title legacy field will be replaced with a regular field and will disappear from the Manage fields page.
tutuploadsmedia_1326924160600.png
You will now get a confirmation message.

Step 8: Activate the language option for each field

tutuploadsStep_8_Activate_the_language_option_for_each_field.png
Click the field name in the Field column. You will need to do this for each field included in the content type.
tutuploadsmedia_1326925225904.png
Check the box to allow the field to be translated. Save the field settings.

Step 9: Create some content and activate the translation feature for that item

tutuploadsStep_9_Create_some_content_and_activate_the_translation_f.png
Click Add content and add a content type that you have already enabled multilingual capabilities for. Choose a language and save your entry.
tutuploadsmedia_1326927322414.png
After you've saved it, there will now be an additional tab on the editing page. Click Translate.
tutuploadsmedia_1326927391598.png
Click add translation in the new dialog box.
tutuploadsmedia_1326927572410.png
Make the translations and save your work. In the example above, I've done the French translation for the title and the body.

Step 10: Repeat for each language

tutuploadsStep_10_Repeat_for_each_language.png
Do the same for each language you want to use on the site.

Step 11: Add a block for the language switcher

tutuploadsStep_11_Add_a_block_for_the_language_switcher.png
Go to Structure, then Blocks and find the Language switcher (Content) and Language switcher (User interface text) blocks.
tutuploadsStep_12_Add_the_block_to_your_site.png
Add one or both of these to your site by specifying the position.
tutuploadsmedia_1326928781631.png
Click Configure on the block page. Click Languages. Choose the visibility settings. The default is to show regardless of language.
tutuploadsmedia_1326928955792.png
In the image above, the block is positioned in the footer. Clicking an icon or a word will change the site language.
tutuploadsmedia_1326929117337.png
Here's a picture of the page after I clicked the Afrikaans flag in the block. Notice that some labels are not translated. You'll need to address those individually as described in Step 5. It may be translated in a language file update at some point in the future, or that word may not exist (or be the same) in the language you chose.
Now you know how to add both interface translations and content translations to a Drupal site. There are a lot of steps and it's easy to get lost in the process. Work slowly if you're a novice, and make sure the early steps work before you move on.