В общем, проблема старая и известная. Правда не на всех рейсурсах заметная. При использовании модуля Metatag, на форму редактирования сущностей добавляется вкладка для индивидуального изменения метатегов. И на ней используется браузер токенов. На больших проектах это может здорово утяжелить форму, что приводит к постоянному подвисанию: после открытия формы браузер долго строит форму (из-за большого кол-ва элементов), или очень долго отрабатывает ajax на форме (при добавлении новых значений во множественных полях).
Далее будут приведены несколько способов, как решить данную проблему.
1. Ограничить размер дерева токенов
Для этого есть готовый модуль Token tweaks. Он дает возможность в админке выбрать максимальный уровень вложенности у токенов. Если нет желания ставить модуль, то достаточно в своем модуле добавить один hook:
function MYMODULE_preprocess_token_tree(&$variables) {
$variables['recursion_limit'] = min(2, $variables['recursion_limit']);
//где 2 - это требуемый уровень вложенности
}
2. Заменить браузер токенов на тот, что использует AJAX
Для этого есть модуль Fast Token Browser. Он подгружает дерево токенов через AJAX. При его использовании отпадает необходимость в ограничении уровня вложенности. Так что этот модуль рекомендую всем проектам, с большим кол-вом токенов.
Предыдущие методы касались оптимизации работы с деревом токенов, что несомненно улучшает ситуацию с формами редактирования. Но недостаточно ;-) Дело в том, что сам модуль Metatag генерирует довольно большой html. Далее займемся оптимизацией именно модуля Metatag.
3. Оптимизируем вкладку Metatag
/**
* Изменения на форме редактирования ноды
*/
function MYMODULE_form_node_form_alter(&$form, &$form_state) {
unset($form['#metatags']);
unset($form['metatags']);
}
/**
* Изменения на форме редактирования термина
*/
function MYMODULE_form_taxonomy_form_term_alter(&$form, &$form_state) {
unset($form['#metatags']);
unset($form['metatags']);
}
/**
* Изменения на форме редактирования пользователя
*/
function MYMODULE_form_user_profile_form_alter(&$form, &$form_state) {
unset($form['#metatags']);
unset($form['metatags']);
}
Проверяем форму редактирования и наслаждаемся результатом.
А что делать, если возможность индивидуально редактировать метатеги все таки необходима?
/**
* Объявляем адреса страниц
* Implements hook_menu().
*/
function MYMODULE_menu() {
$items['node/%node/metatags'] = array(
'title' => 'Edit Metatag',
'page callback' => 'drupal_get_form',
'page arguments' => array('MYMODULE_metatag_edit_form', 0, 1),
'access arguments' => array(0, 1),
'access callback' => '_MYMODULE_metatag_edit_access',
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items['taxonomy/term/%taxonomy_term/metatags'] = array(
'title' => 'Edit Metatag',
'page callback' => 'drupal_get_form',
'page arguments' => array('MYMODULE_metatag_edit_form', 1, 2),
'access arguments' => array(1, 2),
'access callback' => '_MYMODULE_metatag_edit_access',
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
return $items;
}
/**
* Включаем тему админки для данных страниц
* @return array
*/
function MYMODULE_admin_paths() {
$paths = array(
'node/*/metatags' => TRUE,
'taxonomy/term/*/metatags' => TRUE,
);
return $paths;
}
/**
* Доступ к форме редактирования метатегов
* @param $type
* @param $entity
* @return bool
*/
function _MYMODULE_metatag_edit_access($entity_type, $entity){
//Проверяем доступ пользователя к редактированию метатегов
if(!user_access('edit meta tags')){
return FALSE;
}
//Корректируем entity_type для терминов
if($entity_type == 'term'){
$entity_type = 'taxonomy_term';
}
list($entity_id, $revision_id, $bundle) = entity_extract_ids($entity_type, $entity);
//Проверяем, включена ли поддержка метатегов для данной сущности
//(смотрим настройки /admin/config/search/metatags/settings)
if (!metatag_entity_supports_metatags($entity_type, $bundle)) {
return FALSE;
}
return TRUE;
}
//Строим саму форму
/**
* Форма редактирования метатегов
* @param $form
* @param $form_state
* @return mixed
*/
function MYMODULE_metatag_edit_form($form, &$form_state){
$entity_type = isset($form_state['build_info']['args'][0]) ? $form_state['build_info']['args'][0] : FALSE;
$entity = isset($form_state['build_info']['args'][1]) ? $form_state['build_info']['args'][1] : FALSE;
if($entity_type == 'term'){
$entity_type = 'taxonomy_term';
}
list($entity_id, $revision_id, $bundle) = entity_extract_ids($entity_type, $entity);
//Нужно для работы Metatag
$form['#entity'] = array(
'#type' => 'value',
'#value' => $entity,
);
$form['entity_type'] = array(
'#type' => 'value',
'#value' => $entity_type,
);
$form['entity_id'] = array(
'#type' => 'value',
'#value' => intval($entity_id),
);
$form['bundle'] = array(
'#type' => 'value',
'#value' => $bundle,
);
$form['revision_id'] = array(
'#type' => 'value',
'#value' => intval($revision_id),
);
//Пусть модуль Metatag сделает за нас всю работу :-)
metatag_field_attach_form($entity_type, $entity, $form, $form_state, $langcode);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#weight' => 1000,
);
return $form;
}
//Осталось добавить сохранение метатегов
/**
* @param $form
* @param $form_state
*/
function MYMODULE_metatag_edit_form_submit($form, &$form_state){
$entity_type = isset($form_state['values']['entity_type']) ? $form_state['values']['entity_type'] : FALSE;
$entity_id = isset($form_state['values']['entity_id']) ? $form_state['values']['entity_id'] : FALSE;
$bundle = isset($form_state['values']['bundle']) ? $form_state['values']['bundle'] : FALSE;
$revision_id = isset($form_state['values']['revision_id']) ? $form_state['values']['revision_id'] : FALSE;
if($entity_type && $entity_id && $bundle){
metatag_metatags_save($entity_type, $entity_id, $revision_id, $form_state['values']['metatags'], $bundle);
}
}
Во в принципе и всё, что хотел рассказать. Данный способ не проверялся на других типах сущностей и на многоязычном сайте, так что предлагаю Вам потестить его. И несколько скриншотов с результатом работы:
- 24.06.2021
- 71 просмотр