diff --git a/README.txt b/README.txt index 0edb7a9..65f8c5a 100644 --- a/README.txt +++ b/README.txt @@ -26,6 +26,9 @@ The primary features include: * Optional token replacement for node and block CSS and JS, if the Token module is installed a popup token browser will be available. +* Optionally control the weight of the CSS and JS, allowing for exact + positioning of each. + Installation ------------------------------------------------------------------------------ diff --git a/cpn.admin.inc b/cpn.admin.inc index a7ae57e..d6838ee 100644 --- a/cpn.admin.inc +++ b/cpn.admin.inc @@ -54,6 +54,27 @@ function cpn_settings($form, &$form_state) { '#default_value' => variable_get('cpn_aggregation_js', TRUE), ); + // Added weight to the appearance of the CSS & JS in the template. + $form['cpn_weight'] = array( + '#type' => 'fieldset', + '#title' => t('Code loading order / weight'), + '#description' => t('Control the order in which the CSS and JS will be loaded. Changing these can possibly cause problems with other CSS or JS, be sure to test any changes before using them on a production site.
The global code will be loaded first, then per-content type code, then any per-node code, and then any per-block code.
For both values any number may be used - positive or negative, and an integer (whole number) or a float (decimal). Drupal will load items that have the lowest value first, i.e. -100 will be loaded before 100.'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['cpn_weight']['cpn_weight_css'] = array( + '#title' => t('Weight for the added CSS'), + '#type' => 'textfield', + '#default_value' => variable_get('cpn_weight_css', CSS_THEME), + '#description' => t('The default is @css_theme, which causes CSS to be loaded with other files from the theme.', array('@css_theme' => CSS_THEME)), + ); + $form['cpn_weight']['cpn_weight_js'] = array( + '#title' => t('Weight for the added JavaScript'), + '#type' => 'textfield', + '#default_value' => variable_get('cpn_weight_js', JS_THEME), + '#description' => t('The default is @js_theme, which causes JS to be loaded with other files from the theme. Another common value is @js_library, which causes JS to be loaded before other JavaScript libraries, like jQuery.', array('@js_theme' => JS_THEME, '@js_library' => JS_LIBRARY)), + ); + foreach (array('block', 'node') as $entity_type) { $form['cpn_wrapper_' . $entity_type] = array( '#type' => 'fieldset', @@ -181,6 +202,17 @@ function cpn_settings($form, &$form_state) { } /** + * Settings form - validate callback. + */ +function cpn_settings_validate($form, &$form_state) { + foreach (array('css', 'js') as $type) { + if (!is_numeric($form_state['values']['cpn_weight_' . $type])) { + form_set_error('cpn', t('You must select a numeric value for the weight fields.')); + } + } +} + +/** * Settings form - submit callback. */ function cpn_settings_submit($form, &$form_state) { diff --git a/cpn.install b/cpn.install index 97457f9..acc6d06 100644 --- a/cpn.install +++ b/cpn.install @@ -67,27 +67,22 @@ function cpn_uninstall() { file_unmanaged_delete_recursive(variable_get('cpn_path', 'public://cpn')); // Delete variables. - variable_del('cpn_aggregation_css'); - variable_del('cpn_aggregation_js'); - variable_del('cpn_global_css'); - variable_del('cpn_global_css_admin'); - variable_del('cpn_global_css_agree'); - variable_del('cpn_global_js'); - variable_del('cpn_global_js_admin'); - variable_del('cpn_global_js_agree'); + $node_types = array_keys(node_type_get_types()); + foreach (array('css', 'js') as $type) { + variable_del('cpn_aggregation_' . $type); + variable_del('cpn_global_' . $type); + variable_del('cpn_global_' . $type . '_admin'); + variable_del('cpn_global_' . $type . '_agree'); + variable_del('cpn_weight_' . $type); + variable_del('cpn_wrapper_block_' . $type); + variable_del('cpn_wrapper_node_' . $type); + foreach ($node_types as $type) { + variable_del('cpn_' . $type . '_' . $type); + variable_del('cpn_' . $type . '_enabled_' . $type); + } + } variable_del('cpn_path'); variable_del('cpn_syntax_highlighting'); - variable_del('cpn_wrapper_block_css'); - variable_del('cpn_wrapper_block_js'); - variable_del('cpn_wrapper_node_css'); - variable_del('cpn_wrapper_node_js'); - - foreach (array_keys(node_type_get_types()) as $type) { - variable_del('cpn_css_' . $type); - variable_del('cpn_css_enabled_' . $type); - variable_del('cpn_js_' . $type); - variable_del('cpn_js_enabled_' . $type); - } } /** diff --git a/cpn.module b/cpn.module index 7590fc2..5c127c1 100644 --- a/cpn.module +++ b/cpn.module @@ -38,11 +38,18 @@ function cpn_menu() { * Implements hook_page_build(). */ function cpn_page_build(&$page) { + // Optional weights. + $weight = array( + 'css' => variable_get('cpn_weight_css', CSS_THEME), + 'js' => variable_get('cpn_weight_css', JS_THEME), + ); + foreach (array('css', 'js') as $type) { // Only proceed if the 'agree' option was checked and if some code was // actually saved. $agree = variable_get('cpn_global_' . $type . '_agree', FALSE); $code = variable_get('cpn_global_' . $type, ''); + if ($agree && !empty($code)) { // Only proceed if either this is not an admin page or if the 'load on // admin pages too' option was checked. @@ -53,7 +60,7 @@ function cpn_page_build(&$page) { $page['content']['#attached'][$type]['cpn_global'] = array( 'type' => 'file', 'group' => $type == 'css' ? CSS_THEME : JS_THEME, - 'weight' => ($type == 'css' ? CSS_THEME : JS_THEME) - 2, + 'weight' => $weight[$type] - 2, 'data' => $file, 'preprocess' => (bool) variable_get('cpn_aggregation_' . $type, FALSE), ); @@ -296,6 +303,12 @@ function cpn_ctools_render_alter(&$info, &$page, &$context) { if (isset($context['contexts']['argument_entity_id:node_1']->data)) { $node = $context['contexts']['argument_entity_id:node_1']->data; + // Optional weights. + $weight = array( + 'css' => variable_get('cpn_weight_css', CSS_THEME), + 'js' => variable_get('cpn_weight_css', JS_THEME), + ); + // Attach the content type CSS/JS, lighter than the per-page files. foreach (array('css', 'js') as $type) { $file = variable_get('cpn_path', 'public://cpn') . '/' . $node->type . '.' . $type; @@ -303,7 +316,7 @@ function cpn_ctools_render_alter(&$info, &$page, &$context) { $options = array( 'type' => 'file', 'group' => $type == 'css' ? CSS_THEME : JS_THEME, - 'weight' => ($type == 'css' ? CSS_THEME : JS_THEME) - 1, + 'weight' => $weight[$type] - 1, 'preprocess' => (bool) variable_get('cpn_aggregation_' . $type, FALSE), ); $function = 'drupal_add_' . $type; @@ -322,7 +335,7 @@ function cpn_ctools_render_alter(&$info, &$page, &$context) { $options = array( 'type' => 'file', 'group' => ($type == 'css' ? CSS_THEME : JS_THEME), - 'weight' => 100, + 'weight' => $weight[$type], 'preprocess' => (bool) variable_get('cpn_aggregation_' . $type, FALSE), ); $function = 'drupal_add_' . $type; @@ -342,6 +355,12 @@ function cpn_node_view($node, $view_mode, $langcode) { // problem especially for JS. static $previewed = FALSE; + // Optional weights. + $weight = array( + 'css' => variable_get('cpn_weight_css', CSS_THEME), + 'js' => variable_get('cpn_weight_css', JS_THEME), + ); + // Attach the content type CSS/JS, lighter than the per-page files. foreach (array('css', 'js') as $type) { $file = variable_get('cpn_path', 'public://cpn') . '/' . $node->type . '.' . $type; @@ -349,7 +368,7 @@ function cpn_node_view($node, $view_mode, $langcode) { $node->content['#attached'][$type]['cpn_type_' . $node->type] = array( 'type' => 'file', 'group' => $type == 'css' ? CSS_THEME : JS_THEME, - 'weight' => ($type == 'css' ? CSS_THEME : JS_THEME) - 1, + 'weight' => $weight[$type] - 1, 'data' => $file, ); } @@ -371,7 +390,7 @@ function cpn_node_view($node, $view_mode, $langcode) { $node->content['#attached'][$type]['cpn_node_' . $node->nid] = array( 'type' => 'inline', 'group' => $type == 'css' ? CSS_THEME : JS_THEME, - 'weight' => $type == 'css' ? CSS_THEME : JS_THEME, + 'weight' => $weight[$type], 'data' => $output, ); } @@ -389,7 +408,7 @@ function cpn_node_view($node, $view_mode, $langcode) { $node->content['#attached'][$type]['cpn_node_' . $node->nid] = array( 'type' => 'file', 'group' => $type == 'css' ? CSS_THEME : JS_THEME, - 'weight' => $type == 'css' ? CSS_THEME : JS_THEME, + 'weight' => $weight[$type], 'data' => $file, 'preprocess' => $type == 'css' ? variable_get('cpn_aggregation_css', TRUE) : variable_get('cpn_aggregation_js', TRUE), ); @@ -519,11 +538,21 @@ function cpn_preprocess_block(&$vars) { $css = variable_get('cpn_path', 'public://cpn') . '/' . $vars['block']->module . '-' . $vars['block']->delta . '.css'; $js = variable_get('cpn_path', 'public://cpn') . '/' . $vars['block']->module . '-' . $vars['block']->delta . '.js'; if (is_file($css)) { - $options = array('type' => 'file', 'group' => CSS_THEME, 'preprocess' => variable_get('cpn_aggregation_css', TRUE)); + $options = array( + 'type' => 'file', + 'group' => CSS_THEME, + 'weight' => variable_get('cpn_weight_css', CSS_THEME) + 1, + 'preprocess' => variable_get('cpn_aggregation_css', TRUE), + ); drupal_add_css($css, $options); } if (is_file($js)) { - $options = array('type' => 'file', 'group' => JS_THEME, 'preprocess' => variable_get('cpn_aggregation_js', TRUE)); + $options = array( + 'type' => 'file', + 'group' => JS_THEME, + 'weight' => variable_get('cpn_weight_js', JS_THEME) + 1, + 'preprocess' => variable_get('cpn_aggregation_js', TRUE), + ); drupal_add_js($js, $options); } }