2

I'm trying to integrate Impress.js into a Drupal 7 instance, so that I can define a new content type (ie. keynote) for which I use a specific page.tpl.php template.

I build a small module to load impress.js files (both .css and .js) only when I have a node of that content type displaying in full view mode. I'm using preprocess_node_view.

But for some reason, though impress.js is being loaded, the browser returns the fallback message as it wasn't loading correctly.

May it be a problem with jQuery? May it be that the file is not properly loaded?

To test if it is a collision problem between jquery and impress I'd like to unset jquery for that page load, but I'm being unable to do it. (during preprocess_node_view it is too late, but I'm not finding how to do it in preprocess_page).

Do you have any idea?

Also, If anyone has already tried this integration (I dont like the Impress 3D module approximation) and may offer a pointer on where the real problem resides, it would be very appreciated, as I'm starting to get mad.

PS. I didn't find a solution yet. Here is the code i'm using:

  • Module that loads JavaScript and CSS through hook_node_view():

    <?php
    /**
     * Implements hook_node_view()
     */
    function impressintegrator_node_view($node, $view_mode, $langcode) {
      // if node is a presentation, and we're looking at a full node view
      if ($node->type == 'presentacion' && $view_mode == 'full') {
        drupal_add_js(drupal_get_path('module', 'impressintegrator') .'/js/impress.js');
        // and add this css file
        drupal_add_css(drupal_get_path('module', 'impressintegrator') .'/css/impress.css');
      }
    }
    
  • Node body (with PHP Code filter):

    <div id="impress" class="impress-not-supported">
      <div class="fallback-message">
        <p>Tu navegador <b>no soporta las funciones requeridas</b> por impress.js. Por eso, lo que ves es una versión simplificada de la presentación.</p>
        <p>Para una mejor experiencia, recomendamos usar la última versión de <b>Firefox</b>, <b>Chrome</b> o <b>Safari</b>. La incipiente versión 10 de Internet Explorer también <i>debería</i> ser compatible con impress.js.</p>
      </div>    
      <div id="titulo" class="step slide" data-x="-1000" data-y="-1500">                
        <div class="caja1"><p>Slides para la web</p>
        </div>
      </div>
      <div id="documental" class="step slide" data-x="0" data-y="-1500">                
        <div class="cajadocumental"><p>Hacer presentaciones se parece más a crear cómics que a redactar informes. Necesita una dosis extra de creatividad.</p>
        </div>
      </div>
    </div>
    
    <script>
      impress();
    </script>
    

With Firebug I can see 2 errors: "body is null" (in impress.js) and "impress() is not defined" (in page body), though impress.js is loaded (and even giving errors, he he).

This is the hook I had implemented before posting here:

function impressintegrator_node_view($node, $view_mode, $langcode) {
  // if node is a presentation, and we're looking at a full page view
  if ($node->type == 'presentacion' && $view_mode == 'full') {
    drupal_add_js(drupal_get_path('module', 'impressintegrator') .'/js/jmpress.js');
    drupal_add_js(drupal_get_path('module', 'impressintegrator') .'/js/ejecutarjmpress.js');
    // and add this css file
    drupal_add_css(drupal_get_path('module', 'impressintegrator') .'/css/jmpress.css');
  }
}

Thanks for your feedback. The existing module for impress doesn't fit my needs, as I need to create many presentations and managed them as content, no as a view.

Right now i'm trying to use jmpress (as even the creator of that module says the demo is built using jmpress)

For some reason, my function is loading every file (from js to css), but it isn't working. The code to run jmpress is as simple as follows:

jQuery(function() {
    jQuery('#simple').jmpress();
});

But, even with all scritps being loaded, it is not working. As you see, I was using the function you recommend (drupal_add_js) but I don't know how to specify weight of each script, and I don't know how to implement Drupal.behavior (I did a couple of attempts but I think I'm not getting it...

I tried the following code, but have no experience with behaviors and i don't know if I'm missing some dependencies or anything else :)

(function ($) {
  Drupal.behaviors.impressintegrator = {
    attach: function (context, settings) {
      $('#simple').jmpress();
    }
  };
}(jQuery));

From what I understood, I can just call "diapos" even though I'm not declared it previously, and it will even run, but I didn't get anything running so I've probably missed something.

4
  • what is the fallback message ? how does your .js code look - are you using a behavoir ?, maybe try shama.github.com/jmpress.js
    – rémy
    Apr 13, 2012 at 16:06
  • the fallback message is that my browser doesn't support impress.js. That's not true: I am able to run impress.js in a demo .html file. The same html and the same javascript are not working when the js is loaded through the drupal module and the html is included as body of the node.
    – versvs
    Apr 13, 2012 at 17:39
  • I modified my module to add jmpress.js to $styles, instead of impress.js. I changed also the line to effectively launch jmpress. And I'm getting the same kind of error, as if the js wasn't loaded when it really is loaded. So the problem must be elsewhere. The node has the "PHP Code" filter active, just to be sure that i'm not stripping any code. I'm loading jmpress.js in the header. I'm not using behaviour.
    – versvs
    Apr 13, 2012 at 18:09
  • so - how does your javascript code look ?
    – rémy
    Apr 13, 2012 at 18:29

2 Answers 2

1

First off, you should add the javascript and css includes in a preprocess function: yourmodule_preprocess_node()

Also, you never mentioned where/how you are calling impress().init();?

Ideally, you should either add it inline using drupal_add_js() and make sure it has a weight that is higher than the impress.js include or you could wrap it in a Drupal.behaviors in your own custom js (make sure its loaded after).

In case you are thinking about it, you should really avoid putting any css and js in node bodies, its just terrible practice and will likely get shredded by filters.

Also, this is unlikely to collide in any way with jQuery, try adding jQuery in your static demo page to find out.

EDIT

Your behavior code is almost there, it should look like this:

(function ($) {
  Drupal.behaviors.impressintegrator = {
    attach: function (context, settings) {
      $('#simple', context).jmpress(); // notice passing context variable to optimize selector
    }
  };
}(jQuery));

One thing though, you specify $('#simple") in your example, but I don't see it anywhere in your markup. Also the code example from the library link suggests an entirely different approach than you are taking.

However, the main problem is that the "impress-not-supported" class should be added to the body element!

In your behavior, before anything else, do this:

$('body', context).addClass('impress-not-supported');

Also, I've never heard of jmpress, I've been working with impress.js, so you should try including it and using the impress.init() function call as in the project's example.

Finally, to add weights to your javascript includes:

drupal_add_js('path/to/impress', array('group' => JS_LIBRARY, 'every_page' => TRUE, 'weight' => 0'));

You should add the JS_LIBRARY group to the impress.js file and JS_THEME to your custom script. Weight = 0 should be fine for both as libraries get added before theme scripts. Do read up on the drupal_add_js() documentation it explains all of this stuff in detail! :)

4
  • Thanks, Alex! I've given it a try. What you suggest is what i've been trying, but I'm starting to think I'm missing some basic lesson here... as I dont get it working :) I've added extra info to my question.
    – versvs
    Apr 15, 2012 at 9:31
  • I've complemented the answer :)
    – Alex Weber
    Apr 15, 2012 at 14:59
  • Thanks again! I've improved the code of my Behavior :) The mess with #simple and #impress is due to my migration from impress.js to jmpress.js (=jquery-like syntaxis). I wanted to use impress.js (gpl), but i didn't manage to get it running :( While I guess how to build a behavior that launches impress.js (to take js away from node->body), I'll be using jmpress.js, whose only problem is that it requieres jquery >= 1.7.0, while Drupal7Core bundles with jQuery 1.4 (used _js_alter to replace the bundled with 1.7.1 and it loaded OK). Thanks again! Any ideas on launching impress.js with behavior?
    – versvs
    Apr 15, 2012 at 17:13
  • It's trivial, just call it! :) Replace the line "$('#simple', context).jmpress();" with "impress.init();" as long as the impress-not-supported has been added to the body and the library has been loaded before, it should work fine!
    – Alex Weber
    Apr 15, 2012 at 21:37
0

Plan B: Try and use the existing Impress.js module!

1
  • It is a nice module, but doesn't fit my needs. I opened an issue at drupal.org a couple of days ago... And even exchanged a couple of mails with the developer, but his solution (building a multi-view with views) still doesn't fit my project. It is a really cool (easy to install) module that does only one thing but does it really well :)
    – versvs
    Apr 15, 2012 at 9:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.