This is one of those "oh... PHP" issues that is so bizarre it's *almost* funny, except it causes lost hours of work trying to figure out what's happening.
The end result is that the "version" string (or the first character of it) replaces the first character of the JS path. So if your library is version "1.0" and your JS path is "sites/all/modules/mymodule/library.js", the path gets clobbered and turns into "1ites/all/modules/mymodule/library.js". Obviously this causes the JS file to not actually get added to the page, as the path is wrong.
This problem only manifests itself when using the "shorthand" library syntax.
To reproduce. Add a library hook such as this to a custom module:
function mymodule_library() {
$libraries['mylibrary'] = array(
'title' => 'My Module: My Library',
'version' => '1.0',
'js' => array(
drupal_get_path('module', 'mymodule') . '/mylibrary.js',
),
);
return $libraries;
}
Then (for simplicity's sake), in hook_init() add your library to the page:
function mymodule_init() {
drupal_add_library('mymodule', 'mylibrary');
}
You would expect that the path "sites/all/modules/mymodule/mylibrary.js" would be added to the page, but instead "1ites/all/modules/mymodule/mylibrary.js" is. You can change the version number to "2.0" and see that the path becomes "2ites/all/modules/mymodule/mylibrary.js".
This problem stems from this bit of code in drupal_get_library:
$module_libraries[$key] += array(
'dependencies' => array(),
'js' => array(),
'css' => array(),
);
foreach ($module_libraries[$key]['js'] as $file => $options) {
$module_libraries[$key]['js'][$file]['version'] = $module_libraries[$key]['version'];
}
If $file is not an array, but a string, then setting "version" actually just replaces the first letter of the string.
| Comment | File | Size | Author |
|---|---|---|---|
| #20 | 1396892-20-js-libraries.patch | 3.23 KB | dcam |
| #18 | 1396892-18-js-libraries-tests-only.patch | 2.38 KB | dcam |
| #18 | 1396892-18-js-libraries.patch | 3.23 KB | dcam |
| #16 | 1396892-16-js-libraries-tests-only.patch | 1.82 KB | dcam |
| #16 | 1396892-16-js-libraries.patch | 2.67 KB | dcam |
Comments
Comment #1
quicksketchOh, and the quick workaround for developers experiencing this problem, just use the long-form syntax in hook_library for the 'js' file:
Adding the
=> array('group' => JS_DEFAULT)makes it so that the library is defined as an array as drupal_get_library() expects. Seems like the most sane solution would be to allow modules to use the shorthand syntax in hook_library(), but then convert it to a consistent syntax so we don't have these messy confusions.Comment #2
tstoecklerWe stumbled on this in Libraries API.
See libraries_prepare_files(), specifically: http://drupalcode.org/project/libraries.git/blob/623d0058df35cd57d93b5a8...
Comment #3
larowlanhit this today in a 7.x project.
thanks to @boztek for pointing me at this.
Comment #4
larowlanFirst a fail patch, then a pass.
Drupal 8 - 'Now with 70% more magical ponies, llamas and unicorns'™.
(We already have llamas and unicorns in edit module).
Adding backport tag.
Comment #5
nick_schuch commentedSuper bazaar but reproducible in both the testing larowlan has provided and my manual testing via quicksketch's instructions.
I cannot fault this. If anyone has any objections (not with the ponies!) then move back to "Needs work" etc.
Comment #6
quicksketchThanks @larowlan. Nice and simple solution. +1
Comment #7
nick_schuch commentedThis is the basic module that I setup to test this functionality (if others wish to also test).
Comment #8
quicksketch@nick_schuch: What I usually like to do is comment out or remove the "hidden: true" line in test modules so I can enable them directly in the normal UI. There are all kinds of test modules intended for automated testing that are also useful for manual testing.
Comment #9
nick_schuch commentedThat also works. Cheers!
Comment #10
xjm#4 is the patch (not #7).
Comment #11
webchickSo I've nothing against ponies, per se, but it really needs to be a whole lot clearer to people coming at this many months from now trying to figure out why their tests are failing about what exactly this test was aiming to be testing in the first place. :P So augmenting this with some comments or something that explains this better is needed.
Then my follow-up stupid question to that would be, "Why do we allow more than one way to do this in the first place?" That just seems confusing and error-prone (as evidenced by this issue). It seems like it should always be an array, then nothing ever gets clobbered. No?
Comment #12
larowlanThanks @webchick - will tidy up comments etc tomorrow and tone down the goofiness.
Reasons why you shouldn't ask an 11 year old to name a plugin.
Comment #13
larowlanSorry Tony, you had to go!
Comment #14
quicksketchNew version looks good too.
Regarding the short-hand format... I think it's a fine convenience. The syntax for JS/CSS is so crazy verbose I'm happy that there's a short version that just gets something working, then later you can add the extra options for changing your file weight if that's important to you. Although we're talking about adding JS as part of library_info hooks here, we have the same shorthand syntax for #attached as well. Which would you rather write?
In any case, keeping the short syntax for now makes this patch completely backportable to D7, which suffers the same problem.
Comment #15
alexpottCommitted f6b150a and pushed to 8.x. Thanks!
Comment #16
dcam commentedBackported #13 to D7.
Comment #18
dcam commentedLet's try a backport again, this time with the javascript file actually added to the patch.
Comment #19
mgiffordNo longer applies.
Comment #20
dcam commentedRerolled #18.