Integrating Turnjs with Rails 5

Introduction

Turnjs library is a great option to create an ebook with embedded audio and video. We can secure the audio and video assets by using S3 link expiration feature. You can checkout the sample books and different features it offers on it's home page. This article will discuss how to integrate this library with Rails 5.

Setup Dependencies

You can read the requirements for Turnjs on the readme page. I am using jQuery version 3.3.1. Turnjs version: 4.1.0. I copied the jquery, bootstrap.js and turn.js to the vendor/assets/javascripts folder. In application.js, add the turn.js library:

//= require jquery
//= require jquery_ujs
//= require popper  
//= require bootstrap    
//= require turbolinks
//= require fingerprintjs
//= require turn  
//= require_tree .

Due to dependencies, the order of these libraries are important.

Setup Custom Layout

I use a separate layout for the book in app/views/layout called book.html.erb. Because, only those who purchase the course will get access to the course. The layout is as shown below:

<!doctype html>
<!--[if lt IE 7 ]> <html lang="en" class="ie6"> <![endif]-->
<!--[if IE 7 ]>    <html lang="en" class="ie7"> <![endif]-->
<!--[if IE 8 ]>    <html lang="en" class="ie8"> <![endif]-->
<!--[if IE 9 ]>    <html lang="en" class="ie9"> <![endif]-->
<!--[if !IE]><!--> <html lang="en"> <!--<![endif]-->
<head>
<meta name="viewport" content="width = 1050, user-scalable = no" />
<style type='text/css'>
  .hard {
    background-color: #BB8FCE;
    font-size: 1.2em;
    outline: 1 #DDD;
    border-radius: 10px;
  }  
  .pag {
    background-color: #7FB3D5;
    border-radius: 10px;
  }

  p.lesson {
    padding: 10px 10px 10px 10px;
    font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
  }

  .center {
      margin-left: auto;
      margin-right: auto;
      margin-top: 10px;
      display: block
  }

  .page-number {
    margin-top: 10px;
    margin: auto;
    width: 10%;
  }

  #flipbook .shadow,
  #flipbook.shadow{
    -webkit-transition: -webkit-box-shadow 0.5s;
    -moz-transition: -moz-box-shadow 0.5s;
    -o-transition: -webkit-box-shadow 0.5s;
    -ms-transition: -ms-box-shadow 0.5s;

    -webkit-box-shadow: 0 4px 10px #666;
    -moz-box-shadow: 0 4px 10px #666;
    -ms-box-shadow: 0 4px 10px #666;
    -o-box-shadow: 0 4px 10px #666;
    box-shadow: 0 4px 10px #666;
    border-radius: 10px;
  }
  div.box {
    text-align:center;
  }

  #flipbook.centerStart{
    left:260px;
  }
</style>

<%= javascript_include_tag 'application' %>
</head>

<body>

 <%= yield %>

  <script type="text/javascript">
    $(document).ready(function() {
        $("#flipbook").turn({
            width: 1300,
            height: 900,
            autoCenter: true,
          acceleration: true,
          elevation: 50,
          duration: 1000,
          gradients: true
        }); 

        $(document).keydown(function(e){

            var previous = 37, next = 39;

            switch (e.keyCode) {
                case previous:
                    $('#flipbook').turn('previous');
                break;
                case next:
                    $('#flipbook').turn('next');
                break;
            }
        });
    });        
  </script>
</body>
</html>

I am using the class called pag because there is already a builtin page CSS class in Turnjs. You can read the documentation to see all the available CSS classes. The javascript responds to the right and left arrows that navigates to previous or next page.

Setup the Controller

In the controller, I use this custom layout:

class CoursesController < ApplicationController
  layout "book"
  before_action :authenticate_user!

  def index
  end
end

Render the Book in the View

<div id="flipbook" class='centerStart'>
  <div class="hard"> 
  </div>

  <div class='pag'> 
          <div class='page-number'> 
            <p>Page 1</p>
          </div>
    <p class=lesson>
    Lorem Ipsum is simply ...
    </p>

  <div align="center">
      <figcaption>Video 1-1 </figcaption>
      <video width="160" height="120" controls controlsList="nodownload">
        <source src="<%= SecureFile.signed_url("www.joaquinamenabar.com", "video/Video6-15.mov") %>" type="video/mp4">
        Your browser does not support HTML5 video.
      </video>
   </div> 

  <p class=lesson>    
    Lorem Ipsum is simply ...  
    </p>

    <p class='lesson'>
     Lorem Ipsum is simply ...
    </p>

    <p class='lesson'>
     Lorem Ipsum is simply ...
    </p>

  </div>

  <div class='pag'>        
    <div class='page-number'> 
      <p>Page 2</p>
    </div>

      <p class='lesson'>
       Lorem Ipsum is simply ...
      </p>

  <div align="center">
      <figcaption>Audio 1-1 </figcaption>
          <audio controls>
            <source src="<%= SecureFile.signed_url("www.joaquinamenabar.com", "audio/Audio1-17.mp3") %>" controls controlsList="nodownload" type="audio/mpeg">
            Your browser does not support the audio tag.
          </audio>
   </div>        

    <p class='lesson'>
      Lorem Ipsum is simply ...
    </p>

      <div class='box'>
        <%= image_tag("tango-steps.png", size: "550x300", alt: "Tango Steps") %>
      </div>
  </div>

    <div class="pag"> 
    <div class='page-number'> 
      <p>Page 3</p>
    </div>      
  </div>

  <div class="pag"> 
    <div class='page-number'> 
      <p>Page 4</p>
    </div>          
  </div>

    <div class="hard"></div> 
    <div class="hard"></div>
</div>

The book has many pages and each page can have many paragraphs, audio, video or image elements. Each page has a page number. Some pages such as title, copyright etc don't have any page number.


Related Articles


Create your own user feedback survey