metatags_quick.module in Meta tags quick 8.3
Same filename and directory in other branches
Meta tags implemented with FieldAPI/EntityAPI
Module defines new field type 'meta'. Fields of this type are not displayed in HTML. Instead, they add html meta to the head section.
@author Valery L. Lourie <http://drupal.org/user/239562>
File
metatags_quick.moduleView source
<?php
/**
* @file Meta tags implemented with FieldAPI/EntityAPI
*
* Module defines new field type 'meta'.
* Fields of this type are not displayed in HTML.
* Instead, they add html meta to the head section.
*
* @author Valery L. Lourie <http://drupal.org/user/239562>
*/
/**
* Implements hook_menu().
* @todo: remove when core gets rid of hook_menu()
* @see https://api.drupal.org/api/drupal/core!modules!system!system.api.php/function/hook_menu/8
*/
function metatags_quick_menu() {
$items['admin/config/search/metatags_quick'] = array(
'title' => 'Meta tags (quick) settings',
'description' => "Manage your site's book outlines.",
'route_name' => 'metatags_quick_settings',
);
/*
$items['admin/config/search/metatags_quick/path_based'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('metatags_quick_admin_path_based'),
'title' => 'Path-Based Metatags',
'access arguments' => array('edit metatags_quick'),
'file' => 'metatags_quick.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 50
);
$items['admin/config/search/metatags_quick/path_based/edit'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('metatags_quick_admin_path_based_edit'),
'title' => 'Path-Based Metatags',
'access arguments' => array('edit metatags_quick'),
'file' => 'metatags_quick.admin.inc',
'type' => MENU_CALLBACK
);
$items['admin/config/search/metatags_quick/path_based/delete'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('metatags_quick_admin_path_based_delete'),
'title' => 'Path-Based Metatags',
'access arguments' => array('edit metatags_quick'),
'file' => 'metatags_quick.admin.inc',
'type' => MENU_CALLBACK
);
$items['admin/config/search/metatags_quick/settings'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('metatags_quick_admin_settings'),
'title' => 'General',
'access arguments' => array('administer metatags_quick'),
'file' => 'metatags_quick.admin.inc',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
*/
return $items;
}
/**
* Implements hook_permission
* @see http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_permission/7
*/
function metatags_quick_permission() {
return array(
'administer metatags_quick' => array(
'title' => t('Administer metatags(quick)'),
),
'edit metatags_quick' => array(
'title' => t('Edit meta tags'),
),
);
}
/**
* Implements hook_views_api().
*/
function metatags_quick_views_api() {
return array(
'api' => 3,
);
}
/**
* Implements hook_field_access().
*
function metatags_quick_field_access($op, $field, $entity_type, $entity, $account) {
if ($field['type'] == 'metatags_quick' && $op != 'view' && !user_access('edit metatags_quick')) {
return FALSE;
}
return TRUE;
}
/**
* On field load, add meta name to the field data for storage in cache
* and further rendering
* @see http://api.drupal.org/api/drupal/modules--field--field.api.php/function/hook_field_load/7
*
function metatags_quick_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
foreach ($items as $lang => $lang_item) {
foreach ($lang_item as $i => $final_item) {
if (!isset($items[$lang][$i]['meta_name'])) {
$items[$lang][$i]['meta_name'] = $field['settings']['meta_name'];
}
}
}
}
/**
* Implements hook_field_insert
* @see http://api.drupal.org/api/drupal/modules--field--field.api.php/function/hook_field_insert/7
*
function metatags_quick_field_insert($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
// Serialize array items - for the meta robots
foreach ($items as $index => $item) {
if (is_array($item['metatags_quick'])) {
$non_empty = array();
foreach ($item['metatags_quick'] as $subitem) {
if ($subitem) {
$non_empty[] = $subitem;
}
}
$items[$index]['metatags_quick'] = join(',', $non_empty);
}
}
}
/**
* Implements hook_field_update
* @see http://api.drupal.org/api/drupal/modules--field--field.api.php/function/hook_field_update/7
*
function metatags_quick_field_update($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
metatags_quick_field_insert($entity_type, $entities, $field, $instances, $langcode, $items, $age);
}
/**
* Implements hook_page_build().
*/
function metatags_quick_page_build(&$page) {
$language = \Drupal::languageManager()
->getLanguage();
if (variable_get('metatags_quick_use_path_based', 1) && _metatags_quick_path_based_page()) {
$current_path = current_path();
// Try to load path-based meta tags
$path_based_id = db_select('metatags_quick_path_based', 'pv')
->condition('lang', $language->id)
->condition('path', $current_path)
->fields('pv', array(
'id',
))
->execute()
->fetchField();
// if no excact match found - do wildcard search
if ($path_based_id == 0 && strstr($current_path, "/")) {
$parts = explode("/", $current_path);
// iterate through parts
for ($i = count($parts) - 1; $i > 0; $i--) {
// create path
$path = "";
for ($j = 0; $j < $i; $j++) {
$path .= $parts[$j] . "/";
}
// do wildcard query
$path_based_id = db_select('metatags_quick_path_based', 'pv')
->condition('lang', $language->id)
->condition('path', $path . "*")
->fields('pv', array(
'id',
))
->execute()
->fetchField();
// check for results
if ($path_based_id > 0) {
break;
}
}
}
if ($path_based_id > 0) {
$controller = new DrupalDefaultEntityController('metatags_path_based');
$path_entities = $controller
->load(array(
$path_based_id,
));
foreach ($path_entities as $entity) {
field_attach_view('metatags_path_based', $entity, 'default', LANGUAGE_NONE);
}
}
}
}
/**
* Implements hook_menu_local_tasks_alter().
*/
function metatags_quick_menu_local_tasks_alter(&$data, $router_item, $root_path) {
return;
$language = \Drupal::languageManager()
->getLanguage();
$current_path = current_path();
// Don't add meta tags editing tab to admin pages.
if (path_is_admin($current_path)) {
return;
}
// Don't add meta tags editing tab if path based meta tags are disabled.
if (!variable_get('metatags_quick_use_path_based', 1)) {
return;
}
// Don't add meta tags editing tab.
if (variable_get('metatags_quick_remove_tab', 0)) {
return;
}
if (!_metatags_quick_path_based_page()) {
return;
}
$active_item = menu_get_item();
$edit_url = 'admin/config/search/metatags_quick/path_based/edit';
$item = menu_get_item($edit_url);
if ($item['access']) {
$item['#href'] = $edit_url;
$item['localized_options']['query'] = array(
'path' => $current_path,
'lang' => $language->id,
'destination' => $current_path,
);
$data['tabs'][0][$edit_url] = array(
'#theme' => 'menu_local_task',
'#link' => $item,
);
/*
if (isset($data['tabs'][0]['count'])) {
++$data['tabs'][0]['count'];
}
else {
//$data['actions'] = array('count' => 0, 'output' => array());
// Drupal does not display single tab. WTF?
//$data['tabs'][0]['count'] = 2;
}*/
}
}
/**
* Implements hook_field_validate().
*
*/
function metatags_quick_field_validate($obj_type, $object, $field, $instance, $langcode, $items, &$errors) {
if (!isset($field['settings']['max_length'])) {
$field['settings']['max_length'] = 255;
}
foreach ($items as $delta => $item) {
if (!empty($item['metatags_quick']) && !is_array($item['metatags_quick']) && drupal_strlen($item['metatags_quick']) > $field['settings']['max_length']) {
$error = t('%name: the value may not be longer than %max characters.', array(
'%name' => $instance['label'],
'%max' => $field['settings']['max_length'],
));
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => $error,
'message' => $error,
);
}
}
return;
}
/**
* Implements hook_content_is_empty().
*/
function metatags_quick_field_is_empty($item, $field) {
if (empty($item['metatags_quick'])) {
return TRUE;
}
return FALSE;
}
/**
* Implements hook_field_formatter_info().
*
*
function metatags_quick_field_formatter_info() {
$formats = array(
'metatags_quick_link' => array(
'label' => t('Link head element'),
'field types' => array('metatags_quick'),
),
'metatags_quick_plain' => array(
'label' => t('Plain text of metatags_quick'),
'description' => t('Provide the content as plain text.'),
'field types' => array('metatags_quick'),
),
'metatags_quick_title' => array(
'label' => t('Set page title'),
'field types' => array('metatags_quick'),
),
'metatags_quick_default' => array(
'label' => t('Default metatags_quick formatter'),
'description' => t('Add meta to html head.'),
'field types' => array('metatags_quick'),
),
);
return $formats;
}
/**
* Implements hook_field_formatter_view().
*
function metatags_quick_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'metatags_quick_link':
foreach ($items as $delta => $item) {
_metatags_quick_add_head(array(
'type' => 'link',
'name' => $item['meta_name'],
'content' => $item['metatags_quick'],
));
}
// Hide element.
$element = array('#markup' => '', '#printed' => TRUE);
break;
case 'metatags_quick_plain':
foreach ($items as $delta => $item) {
$element[$delta] = array('#markup' => $item['metatags_quick']);
}
break;
case 'metatags_quick_title':
// In case we get a multiple field, we concat the values with ' - ', just
// to have some sane handling.
$title = array();
foreach ($items as $delta => $item) {
$title[] = $item['metatags_quick'];
}
if (!empty($title)) {
drupal_set_title(join(' - ', $title));
}
// Hide element.
$element = array('#markup' => '', '#printed' => TRUE);
break;
case 'metatags_quick_default':
foreach ($items as $delta => $item) {
_metatags_quick_add_head(array(
'type' => 'default',
'name' => $item['meta_name'],
'content' => $item['metatags_quick'],
'entity' => $object,
'entity_type' => $object_type,
));
}
// Hide element.
$element = array('#markup' => '', '#printed' => TRUE);
break;
}
return $element;
}
/**
* Implements hook_field_widget_info().
*
function metatags_quick_field_widget_info() {
return array(
'metatags_quick_textarea' => array(
'label' => t('Text area'),
'field types' => array('metatags_quick'),
),
'metatags_quick_textfield' => array(
'label' => t('Text field'),
'field types' => array('metatags_quick'),
),
'metatags_quick_checkboxes' => array(
'label' => t('Checkboxes'),
'field types' => array('metatags_quick'),
),
);
}
/**
* Implements hook_field_settings_form().
*
function metatags_quick_field_settings_form($field, $instance) {
$settings = $field['settings'];
if (empty($settings['meta_name'])) {
preg_match('/field_(.*)/', $instance['field_name'], $matches);
$settings['meta_name'] = $matches[1];
}
$form['meta_name'] = array(
'#type' => 'textfield',
'#title' => t('Meta name'),
'#default_value' => $settings['meta_name'],
'#description' => t('Meta name (defaults to the field name)'),
'#required' => TRUE,
);
$form['max_length'] = array(
'#type' => 'textfield',
'#title' => t('Maximum length'),
'#default_value' => isset($settings['max_length']) ? $settings['max_length'] : 255,
'#required' => TRUE,
'#description' => t('The maximum length of the field in characters.'),
'#element_validate' => array('_element_validate_integer_positive'),
'#disabled' => field_has_data($field),
);
return $form;
}
/**
* Implements hook_field_instance_settings_form().
* http://api.drupal.org/api/drupal/modules--field_ui--field_ui.api.php/function/hook_field_instance_settings_form/7
*
function metatags_quick_field_instance_settings_form($field, $instance) {
$settings = $instance['settings'];
if ($instance['widget']['type'] == 'metatags_quick_checkboxes') {
$form['options'] = array(
'#type' => 'textfield',
'#title' => t('Possible tags'),
'#maxlength' => variable_get('metatags_quick_default_field_length', 255),
'#default_value' => $settings['options'],
'#description' => t('Possible values, separated by comma'),
'#required' => TRUE,
);
return $form;
}
}
/**
* Implements hook_field_widget_form().
*
function metatags_quick_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $base) {
$element = $base;
switch ($instance['widget']['type']) {
case 'metatags_quick_textfield':
$addition = array(
'#type' => 'textfield',
'#maxlength' => isset($field['settings']['max_length']) ? $field['settings']['max_length'] : variable_get('metatags_quick_default_field_length', 255),
'#default_value' => isset($items[$delta]['metatags_quick']) ? $items[$delta]['metatags_quick'] : NULL,
);
break;
case 'metatags_quick_checkboxes':
if (!isset($items[$delta]['metatags_quick'])) {
$items[$delta]['metatags_quick'] = $instance['default_value'][0]['metatags_quick'];
}
if (isset($items[$delta]['metatags_quick']) && !is_array($items[$delta]['metatags_quick'])) {
$items[$delta]['metatags_quick'] = explode(',', $items[$delta]['metatags_quick']);
}
if ($items[$delta]['metatags_quick'] === NULL) {
$default_checkboxes = explode(',', $instance['settings']['options']);
$items[$delta]['metatags_quick'] = array_fill_keys($default_checkboxes, '');
}
$addition = array(
'#type' => 'checkboxes',
'#options' => drupal_map_assoc(isset($instance['settings']['options']) ? explode(',', $instance['settings']['options']) : array('noindex', 'nofollow')),
'#default_value' => $items[$delta]['metatags_quick'],
);
break;
default:
$addition = array(
'#type' => 'textarea',
'#default_value' => isset($items[$delta]['metatags_quick']) ? $items[$delta]['metatags_quick'] : NULL,
'#rows' => 5,
);
}
$element['metatags_quick'] = $base + $addition;
return $element;
}*/
// Private functions area, may change without prior notice.
// Adds meta tag to internal storage that will be processed during page build.
function _metatags_quick_add_head($item = FALSE) {
static $added_meta = array();
static $meta_data = array();
$token_service = \Drupal::service('token');
if (!empty($added_meta[$item['name']])) {
return;
}
// Only output meta if content is not empty.
if ($item['content']) {
$content = $item['content'];
if (!empty($item['entity_type']) && !empty($item['entity'])) {
$token_service
->replace($content, array(
$item['entity_type'] => $item['entity'],
));
}
else {
$content = $token_service
->replace($content);
}
// (Not nice) hack to separate multiple tags returned by token.
$content = preg_replace('/<\\/a><a/', '<\\/a>, <a', $content);
$content = trim(strip_tags($content));
$item['content'] = $content;
$meta_data[] = $item;
if (empty($item['type'])) {
$item['type'] = 'default';
}
switch ($item['type']) {
case 'link':
// Unset an existing html head link with the same rel attribute, assuming that
// the array key has been built by drupal_add_html_head_link().
$head_elements =& drupal_static('drupal_add_html_head');
foreach ($head_elements as $key => $head_element) {
// If an existing key starts with 'drupal_add_html_head_link:[name]', unset it.
if (strpos($key, 'drupal_add_html_head_link:' . $item['name']) === 0) {
$head_elements[$key]['#access'] = FALSE;
}
}
$attributes = array(
'rel' => $item['name'],
'href' => url($item['content']),
);
drupal_add_html_head_link($attributes);
break;
case 'default':
default:
$element = array(
'#tag' => 'meta',
'#attributes' => array(
'name' => $item['name'],
'content' => $item['content'],
),
);
drupal_add_html_head($element, 'metatags_quick_' . $item['name']);
}
if ($item['name'] == 'title') {
$element = array(
'#tag' => 'title',
'#value' => $item['content'],
);
drupal_add_html_head($element, 'metatags_quick_' . $item['name']);
}
}
$added_meta[$item['name']] = TRUE;
}
// Default settings array
function _metatags_quick_settings_default() {
return array(
'use_front' => FALSE,
'use_path_based' => FALSE,
);
}
/**
* Determine if current page has to be served by path based
* (not entity based) meta tags set.
*/
function _metatags_quick_path_based_page() {
$router_item = menu_get_item();
$path_based = TRUE;
foreach ($router_item['map'] as $map_item) {
if ($map_item instanceof \Drupal\node\Entity\Node) {
$path_based = FALSE;
break;
}
}
return $path_based;
}
/*
* Implements hook_migrate_api().
*/
function metatags_quick_migrate_api() {
$api = array(
'api' => 2,
);
return $api;
}
Functions
Name![]() |
Description |
---|---|
metatags_quick_field_is_empty | Implements hook_content_is_empty(). |
metatags_quick_field_validate | Implements hook_field_validate(). |
metatags_quick_menu | Implements hook_menu(). @todo: remove when core gets rid of hook_menu() |
metatags_quick_menu_local_tasks_alter | Implements hook_menu_local_tasks_alter(). |
metatags_quick_migrate_api | |
metatags_quick_page_build | Implements hook_field_access(). |
metatags_quick_permission | Implements hook_permission |
metatags_quick_views_api | Implements hook_views_api(). |
_metatags_quick_add_head | |
_metatags_quick_path_based_page | Determine if current page has to be served by path based (not entity based) meta tags set. |
_metatags_quick_settings_default |