diff --git a/metatag.inc b/metatag.inc index 0a57517..b1d0f56 100644 --- a/metatag.inc +++ b/metatag.inc @@ -56,7 +56,15 @@ class DrupalDefaultMetaTag implements DrupalMetaTagInterface { } public function getForm(array $options = array()) { - return array(); + $form = array(); + $form['allow_override'] = array( + '#type' => 'checkbox', + '#title' => t('Allow override'), + '#description' => t('Allow the parent configuration to override this one if the value is empty.'), + '#default_value' => isset($this->data['allow_override']) ? $this->data['allow_override'] : 0, + '#weight' => 20, + ); + return $form; } public function getValue(array $options = array()) { @@ -158,6 +166,7 @@ class DrupalDefaultMetaTag implements DrupalMetaTagInterface { class DrupalTextMetaTag extends DrupalDefaultMetaTag { public function getForm(array $options = array()) { + $form = parent::getForm($options); $options += array( 'token types' => array(), ); @@ -281,6 +290,7 @@ class DrupalListMetaTag extends DrupalDefaultMetaTag { } public function getForm(array $options = array()) { + $form = parent::getForm($options); $form['value'] = isset($this->info['form']) ? $this->info['form'] : array(); $form['value'] += array( @@ -307,6 +317,7 @@ class DrupalListMetaTag extends DrupalDefaultMetaTag { class DrupalDateIntervalMetaTag extends DrupalDefaultMetaTag { public function getForm(array $options = array()) { + $form = parent::getForm($options); $form['value'] = array( '#type' => 'textfield', '#title' => t('@title interval', array('@title' => $this->info['label'])), diff --git a/metatag.module b/metatag.module index d30e3d0..7a54b7e 100644 --- a/metatag.module +++ b/metatag.module @@ -1036,10 +1036,29 @@ function metatag_metatags_view($instance, array $metatags = array(), array $opti $options['instance'] = $instance; + $overrides = array(); foreach ($metatags as $metatag => $data) { if ((!empty($data['value']) || (isset($data['value']) && is_numeric($data['value']))) && $metatag_instance = metatag_get_instance($metatag, $data)) { $output[$metatag] = $metatag_instance->getElement($options); + // If overrides are allowed for this metatag and the metatag is empty, + // flag that we need to apply overrides. + if (empty($output[$metatag]) && !empty($data['allow_override'])) { + $overrides[] = $metatag; + } + } + // If overrides are allowed for this metatag, flag that we need to apply + // overrides. + elseif (!empty($data['allow_override'])) { + $overrides[] = $metatag; + } + } + + // If there are any metatags that require overriding, do so. + if ($overrides) { + $instances = metatag_config_get_parent_instances($instance, TRUE, FALSE); + if ($instances) { + metatag_metatags_apply_overrides($output, $instances, $overrides, $options); } } @@ -1050,6 +1069,48 @@ function metatag_metatags_view($instance, array $metatags = array(), array $opti return $output; } +/** + * Handle applying parent instance overrides to metatags. + * + * @param array $output + * The metatag output array. + * @param array $instances + * The parent instances to get overriding metatags from. + * @param array $overrides + * The metatag names that are to be overridden. + * @param array $options + * The options to use to generate the metatags. + */ +function metatag_metatags_apply_overrides(&$output, $instances, $overrides, $options) { + // Get the instance we are currently interested in. + $instance = array_shift($instances); + + // Get metatags for this instance. + $metatags = metatag_config_load_with_defaults($instance); + + foreach ($overrides as $key => $metatag) { + $data = $metatags[$metatag]; + if ((!empty($data['value']) || (isset($data['value']) && is_numeric($data['value']))) + && $metatag_instance = metatag_get_instance($metatag, $data)) { + $output[$metatag] = $metatag_instance->getElement($options); + // If we have a value or overrides aren't allowed at this level, remove + // them from the list of overrides. + if (!empty($output[$metatag]) || empty($data['allow_override'])) { + unset($overrides[$key]); + } + } + // If overrides aren't allowed at this level, remove them from the list of + // overrides. + elseif (empty($data['allow_override'])) { + unset($overrides[$key]); + } + } + + if ($overrides && $instances) { + metatag_metatags_apply_overrides($output, $instances, $overrides, $options); + } +} + function metatag_metatags_values($instance, array $metatags = array(), array $options = array()) { $values = array(); @@ -1191,6 +1252,12 @@ function metatag_metatags_form(array &$form, $instance, array $metatags = array( $metatag_form['#access'] = $form['metatags']['#access']; } + // Wrap the form in a fieldset as it will likely contain multiple fields. + $metatag_form = array( + '#type' => 'fieldset', + '#title' => isset($metatag_form['value']['#title']) ? $metatag_form['value']['#title'] : '', + ) + $metatag_form; + if (!empty($metatag_info['group'])) { $group_key = $metatag_info['group']; if (isset($info['groups'][$group_key]['label']) && !isset($form['metatags'][$langcode][$group_key])) { @@ -1931,14 +1998,18 @@ function metatag_filter_values_from_defaults(array &$values, array $defaults = a /** * Return all the parents of a given configuration instance. * - * @param $instance + * @param string $instance * A meta tag configuration instance. + * @param array $include_global + * Whether or not to include the global instance in the parents array. + * @param array $include_instance + * Whether or not to include the given instance in the parents array. * - * @return + * @return array * An array of instances starting with the $instance parameter, with the end * of the array being the global instance. */ -function metatag_config_get_parent_instances($instance, $include_global = TRUE) { +function metatag_config_get_parent_instances($instance, $include_global = TRUE, $include_instance = TRUE) { $parents = array(); $segments = explode(':', $instance); while (count($segments) > 0) { @@ -1948,6 +2019,9 @@ function metatag_config_get_parent_instances($instance, $include_global = TRUE) if ($include_global && end($parents) !== 'global') { $parents[] = 'global'; } + if (!$include_instance) { + array_shift($parents); + } reset($parents); return $parents; }