Full width video header with Drupal 7 using Bootstrap 3
Full width video header with Drupal 7 using Bootstrap 3
Note Drupal 7 and Bootstrap 3 have been used for this blog post

In one of my Drupal 7 projects I had to make a full width video header. Normally, I always prefer using Bootstrap and leverage the extra pain of creating own CSS. Anyway, I thought there must me some ready made module that does that. I found some modules that helps to render the video but unfortunately, it was not enough. So, I decided to use some existing module for rendering the video and do the rest of the magic manually. Let me walk you through step by step.

STEP : 1

I have used video.js module for rendering the video. So, click the link and download and install the module. After installing, enable the module.

For, our purpose we don’t need the Live Streaming part.

STEP : 2

Then I have created a “Content Type” called “Video” with “Publishing Options” as “Published” and no commenting, no available menu and no author information to display. In “Manage Fields”, I have created a field called “Video” of “Field Type” “File”. In the edit part of the field, I have used “mp4, webm, flv, ogv” as “Allowed file extensions” and I have also increased the “Maximum upload” size to 25 MB. 

This max size has to be smaller or equal to the max upload file size of your server. If you don’t how how to increase the size in the server then leave it to default and make sure that the video you will be using is smaller or equal to the default value. 

Then I have used “Unlimited” as the “Number of values” and checked the “Enable Display field”.

Then I have created another field called “Video Poster” of “Field Type” “Image”. In the edit part of the field, I have used “png, gif, jpg, jpeg” as “Allowed file extensions” and checked the “Required fileld” and checked the “Enable Title field” and “Enable Alt field”. Finally, I have chosen, “1” as the “Number of values” and left everything else as it is. 

The reason to have an image as mandatory is, if the browser does not support video it can fall back to the image. On the other hand, if in future, I want to display a full width image and not a video I can just delete all the videos or just uncheck the “Display” option from the video.

STEP : 3

Now, we will add a content of type of “Video” that we created in STEP : 2. Give “Home Page Video” as the Title of the content and upload any number of videos and an image. 

Here, two things are very important. 1) We always want to only one video which is set to Display from the uploaded ones. If there is no video set to Display or no video uploaded at all, we will fall back to image. If there is a video set to display, then we will use the image as a poster for the video.

2) While creating the content, check the url carefully. The node number mentioned here (e.g 1 or any number) is the id of the node which we will be targetting from our code very soon.

STEP : 4

In my code side, I have a sub theme, let's call it “my_theme” which is actually a subtheme of Bootstrap. Inside my subtheme I have created a folder called “includes” and there I have created a file called “functions.php” and it has the following code snippet

function get_field_from_node($node_id, $which_field) {
    $node = node_load($node_id);
    $field = field_get_items('node', $node, $which_field);
    if ($field != NULL) {
        return $field;
    }
}

Then I have created another file in the “includes” folder called “header_video.php” and it has the following code snippet

$video_list = get_field_from_node(1, 'field_video');//this is node id mentioned in STEP : 3
$poster = get_field_from_node(1, 'field_video_poster');//this is node id mentioned in STEP : 3
$activeVideoFound = FALSE;
if (count($video_list) > 0) {
    foreach ($video_list as $video) {
        if ($video != NULL) {
            extract($video);
            if ($display === "1") {
                $url = file_create_url($uri);
                $poster_url = file_create_url($poster[0]["uri"]);
                $html = <<<html<br>
                <div align="center" class="video-container embed-responsive embed-responsive-16by9">                       
                    <video autoplay="autoplay" loop="loop" muted="muted" preload="auto" class="embed-responsive-item">
                        <source src="{$url}">
                            Your browser does not support the video tag. I suggest you upgrade your browser.
                    </video>
                    <div class="poster hidden">
                        <img src="{$poster_url}" alt="{$poster[0][" alt"]}"="">
                    </div>                       
                    <h1>Welcome to My Site</h1>
                    <p>{$description}</p>
                    <a href="#" id="goDown">
                        <i class="fa fa-angle-down bounce"></i>
                    </a>  
                </div>
                 
HTML;
                $activeVideoFound = TRUE;     
                echo $html;
                break;
            }
        }
    }
}
if ($activeVideoFound === FALSE) {
    $url = file_create_url($poster[0]["uri"]);
    $html = <<<html<br>
                    <div align="center" class="poster-container">
                        <div class="poster">
                            <img src="{$url}" alt="{$poster[0][" alt"]}"="">
                        </div>                       
                        <h1>Welcome to My Site</h1>
                        <p>{$poster[0]["title"]}</p>
                        <a href="#" id="goDown">
                            <i class="fa fa-angle-down bounce"></i>
                        </a>                   
                    </div>   
                     
HTML;
   echo $html;
}

In the code above, I am calling the “get_field_from_node()” function from “functions.php” and passing it two parameters. a) node id b) field name (while creating a field, drupal automatically generates this name for the field).

f there are videos uploaded I am looping through and trying to get the one which has been set to display. If a video is found, I am setting the uploaded image as the poster of the video and breaking out of the loop. If no video found to be displayed, I am just putting the uploaded image as a full width header.

STEP : 5

In my “my_theme” folder I created another folder called “templates” and created a new file called “page--front.tpl.php”. Here I have linked my functions.php file like below

//php code block
require_once DRUPAL_ROOT . '/sites/all/themes/my_theme/includes/functions.php';

Then in the same file I have following code snippet 

<div id="root">
   //php code block
    if (drupal_is_front_page()) {
        include DRUPAL_ROOT . '/sites/all/themes/my_theme/includes/header_video.php';
    }
 
    <div id="wrapper">
<div class="container-fluid">
     <!--?php print render($page['content']); ?-->
</div> <!--Container Close-->
</div> <!--Wrapper Close-->
 <div id="root_footer"></div>
</div><!--Root Close-->
<div id="footer">
    <footer class="footer container">
         //php code block
         print render($page['footer']);
    </footer>
</div>

LAST STEP : CSS

In my main css linked to the site I have the following styles

.video-container video {
    z-index: -1;
    opacity: 0.45;
}
 
.video-container h1 {
    color: #333;
    font-size: 5em;
    margin-top: 16%;
    padding: 10px;
    font-weight: bold;
}
.video-container p {
    color: #333;
    font-size: 1.5em;
    font-style: italic;
}
 
.video-container a#goDown i {
    color: #333;
    font-size: 4em;
    margin-top: 18%;
}
 
.poster-container{
    position: relative;
    display: block;
    height: 0;
    overflow: hidden;
    padding-bottom: 52.25%;
}
.poster {
    background-position: center center;
    background-attachment: fixed;
    background-size: cover;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-backgound-size: cover;  
}
.poster img{
    width: 100%;
    z-index: -1;
}
.poster-container h1{
    position: absolute;
    width: 100%;
    left: 0;
    color: #000;
    font-size: 5em;
    top: 30%;
    padding: 10px;
    font-weight: bold;
}
.poster-container p{
    position: absolute;
    display: block;
    width: 100%;
    left: 0;
    top: 39%;
    color: #000;
    font-size: 1.5em;
    font-style: italic;
}
 
.poster-container a#goDown i {
    position: absolute;
    width: 100%;
    left: 0;
    color: #000;
    font-size: 4em;
    top: 58%;
}
@-moz-keyframes bounce {
    0%, 20%, 50%, 80%, 100% {
        transform: translateY(0);
    }
    40% {
        transform: translateY(-30px);
    }
    60% {
        transform: translateY(-15px);
    }
}
 
@keyframes bounce {
    0%, 20%, 50%, 80%, 100% {
        -ms-transform: translateY(0);
        transform: translateY(0);
    }
    40% {
        -ms-transform: translateY(-8px);
        transform: translateY(-8px);
    }
    60% {
        -ms-transform: translateY(-2px);
        transform: translateY(-2px);
    }
}
 
.bounce {
    -webkit-animation: bounce 2s infinite;
    animation: bounce 2s infinite;
} 

 

February 25, 2016
Jahan Sarwar