diff --git a/libraries.api.php b/libraries.api.php index ac09743..17c086a 100644 --- a/libraries.api.php +++ b/libraries.api.php @@ -164,8 +164,16 @@ * Note that in this group the 'versions' property is no longer available. * - pre-load: Callbacks registered in this group are applied directly * before this library is loaded. At this point the library contains - * variant-specific information, if specified. Note that in this group the - * 'variants' property is no longer available. + * variant-specific information, if specified, and following additional + * information is available: + * - $library['variant']: The variant of the library that is about to be + * loaded. + * The following pre-load callbacks are available for all libraries: + * - libaries_replace_filenames: Use this callback if your library files + * have version- or variant-dependant filenames. The callback replaces + * all occurences of '!version' in filenames with the detected library + * version and all occurences of '!variant' with the variant. + * Note that in this group the 'variants' property is no longer available. * - post-load: Callbacks registered in this group are applied directly * after this library is loaded. At this point, the library contains a * 'loaded' key, which contains the number of files that were loaded. diff --git a/libraries.info b/libraries.info index 208a14e..b70306e 100644 --- a/libraries.info +++ b/libraries.info @@ -2,3 +2,5 @@ name = Libraries description = Allows version dependent and shared usage of external libraries. core = 7.x files[] = tests/libraries.test +; We use format_string() in libraries_replace_filenames() +dependencies[] = system (>=7.9) diff --git a/libraries.module b/libraries.module index c67ce79..bed0709 100644 --- a/libraries.module +++ b/libraries.module @@ -311,6 +311,58 @@ function libraries_detect_dependencies(&$library, $version = NULL, $variant = NU } /** + * Library pre-load callback to replace the version and variant in filenames. + * + * This callback allows to specify a filename as e.g. + * example-!version-!variant.js in hook_libraries_info(). It turns that into + * e.g. example-1.2.3-minified.js before loading the library. + * + * @param $library + * An associative array of library information or a part of it, passed by + * reference. + * @param $version + * If the library information belongs to a specific version, the version + * string. NULL otherwise. + * @param $variant + * If the library information belongs to a specific variant, the variant name. + * NULL otherwise. + * + * @see libraries_invoke() + */ +function libraries_replace_filenames(&$library, $version = NULL, $variant = NULL) { + // Both the 'files' property and the 'integration files' property contain file + // declarations, and we want to replace both. + $file_types = array(); + if (isset($library['files'])) { + $file_types[] = &$library['files']; + } + if (isset($library['integration files'])) { + // Integration files are additionally keyed by module. + foreach ($library['integration files'] as &$integration_files) { + $file_types[] = &$integration_files; + } + } + foreach ($file_types as &$files) { + // Go through all supported types of files. + foreach (array('js', 'css', 'php') as $type) { + if (isset($files[$type])) { + foreach ($files[$type] as $old => $options) { + unset($files[$type][$old]); + + $args = array('!version' => $library['version']); + // A library can be loaded without specifying a variant. + if (isset($library['variant'])) { + $args['!variant'] = $library['variant']; + } + $new = format_string($old, $args); + $files[$type][$new] = $options; + } + } + } + } +} + +/** * Returns information about registered libraries. * * The returned information is unprocessed; i.e., as registered by modules. @@ -589,6 +641,8 @@ function libraries_load($name, $variant = NULL) { // of the library files below. $library['variants'] += array($variant => array('installed' => FALSE)); $library = array_merge($library, $library['variants'][$variant]); + // Make the variant available to 'pre-load' and 'post-load' callbacks. + $library['variant'] = $variant; } // Regardless of whether a specific variant was requested or not, there can // only be one variant of a library within a single request. diff --git a/tests/libraries.test b/tests/libraries.test index c361bcd..1675077 100644 --- a/tests/libraries.test +++ b/tests/libraries.test @@ -122,6 +122,24 @@ class LibrariesTestCase extends DrupalWebTestCase { $this->verbose('Actual:
' . $library['error message']); $this->assertEqual($library['error message'], $error_message, 'Correct error message for an incompatible dependency'); + // Test libraries_replace_filename(). + $library = array( + 'version' => '1', + 'files' => array('js' => array('example-!version.js' => array())), + ); + libraries_replace_filenames($library); + $this->verbose(key($library['files']['js'])); + $this->assertEqual(key($library['files']['js']), 'example-1.js', 'libraries_replace_filename() replaces the version correctly.'); + $library = array( + 'version' => '1', + 'variant' => 'variant-1', + 'files' => array('js' => array('example-!variant.js' => array())), + ); + libraries_replace_filenames($library); + $this->verbose(var_export($library['files'], TRUE)); + $this->assertEqual(key($library['files']['js']), 'example-variant-1.js', 'libraries_replace_filename() replaces the variant correctly.'); + + // Test that library information is found correctly. $expected = array( 'name' => 'Example files', @@ -340,6 +358,7 @@ class LibrariesTestCase extends DrupalWebTestCase { $expected['info callback'] = 'applied (version 1, variant example_variant)'; $expected['pre-detect callback'] = 'applied (version 1, variant example_variant)'; $expected['post-detect callback'] = 'applied (variant example_variant)'; + $expected['variant'] = 'example_variant'; $library = libraries_load('example_callback', 'example_variant'); $this->verbose('Expected:
' . var_export($expected, TRUE) . '
'); $this->verbose('Actual:
' . var_export($library, TRUE) . '
');