Drupal 7 override jquery js file in custom theme

2019-05-05 03:13发布

问题:

Is it possible to rewrite/override a default Drupal 7.26 jquery used in custom template scripts variable ?

I mean one of the js files:

<script type="text/javascript" src="http://drupal.dev/misc/jquery.js?v=1.4.4"></script>

by one which comes by custom theme ?

I tried this in sites/all/MYTPL/template.php but it doesn't work:

$scripts['misc/jquery.js']['data'] = $base_theme . '/js/packages/jquery-2.1.0.min.js';

I would like to know if someone managed it without using any modules such as jQuery Update ?

=== UPDATED ===

Actually I solved it by help of accepted answer with some modifications based on @cojomojo 's answer:

function THEMEname_js_alter(&$javascript) {
    // Swap out jQuery to use an updated version of the library.
    $javascript['misc/jquery.js']['data'] = drupal_get_path('theme', 'THEMEname') . '/js/packages/jquery-2.1.0.min.js';
}

回答1:

Use this code inside your theme's template.php file, in hook_js_alter.

function [YOUR_THEME]_js_alter(&$js)
{
    $jqKey = "my-new-jquery"; // a key for new jquery file entry
    $js[$jqKey] = $js['misc/jquery.js']; // copy the default jquery settings, so you don't have to re-type them.
    $js[$jqKey]['data'] = "https://code.jquery.com/jquery-2.1.0.min.js"; // the path for new jquery file.
    $js[$jqKey]['version'] = '2.1.0'; // your jquery version.

    unset($js['misc/jquery.js']); // delete drupal's default jquery file.
}


回答2:

So you have a few options to do this. Here they are:

You can use hook_js_alter like so:

<?php
function hook_js_alter(&$javascript) {
  // Swap out jQuery to use an updated version of the library.
 $javascript['misc/jquery.js']['data'] =         drupal_get_path('module', 'jquery_update') . '/jquery.js';
}
?>

Or in order to avoid breakage like 2pha mentioned you can run two versions of jquery side by side. jQuery already has the functionality to run along side a different version of jQuery (or, really, along side any other JavaScript library that uses the $ symbol as a function or variable). This is the noConflict() function. You can view the API page here: http://api.jquery.com/jQuery.noConflict/

To use this functionality within your project, simply tell the browser about your new jQuery library and that you'll be referencing it via your custom noConflict identifier. Here is an example of how you would implement this in a custom theme.

MyTheme/page.tpl.php

<head>
  <title><?php print $head_title; ?></title>
  <?php print $head; ?>
  <?php print $styles; ?>
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
  <script type="text/javascript">
    var $jq = jQuery.noConflict();
  </script>
  <?php print $scripts; ?>
</head>

Another possible method is to swap jQuery with the preprocess page like so:

<?php
function yourModuleOrThemeName_preprocess_page(&$variables) {
  // exclude backend pages to avoid core js not working anymore
  // you could also just use a backend theme to avoid this
  if (arg(0) != 'admin' || !(arg(1) == 'add' && arg(2) == 'edit') || arg(0) != 'panels' || arg(0) != 'ctools') {
    $scripts = drupal_add_js();
    $new_jquery = array(drupal_get_path('theme', 'YOURTHEME') . '/js/jquery-1.7.1.min.js' => $scripts['core']['misc/jquery.js']);
    $scripts['core'] = array_merge($new_jquery, $scripts['core']);
    unset($scripts['core']['misc/jquery.js']);
    $variables['scripts'] = drupal_get_js('header', $scripts);
  }
}
?>

To me the best method would be to either run two version of jQuery side by side (the version that Drupal 7 uses by default and whatever your theme requires) or swapping jQuery with the preprocess page. The hook_js_alter has potential for breaking anything that requires the different version of jQuery. All the potential ways to do what you ask are here: https://drupal.org/node/1058168



回答3:

Maybe use the hook hook_js_alter.
Keep in mind though that other modules will depend on jQuery and if they use something that has changed between versions, you may encounter problems.