Приглашаю к тестированию модуля Handy Alias (синонимы для словарей, терминов и нод)

Главные вкладки

Аватар пользователя Stutzer Stutzer 23 августа 2010 в 21:42

Как-то давным-давно я написал анонс модуля, решающего некоторые проблемы с красивыми адресами, но архив с исходниками в том посте так и не появился, хотя многие его с нетерпением ждали. Причиной тому была его тотальная сырость модуля и отсутствие времени на тот момент.
Не прошло и года, как время и силы таки нашлись, так что прошу любить и жаловать!

Если совсем вкратце, то суть этого модуля можно изложить примерно так:
Особо отъявленные перфекционисты часто негодуют при виде адресов типа такого:
dokumenty/zakonoproekty/prinyatie/zakon-o-zaprete-alkogolya. Словом, транслит sucks!
Хотелось бы иметь возможность настраивать pathauto таким образом, чтобы адреса получались вот такими:
docs/law/accepted/no-alcohol-law.html.
Именно этим и занимается модуль Handy Alias, о котором пойдет речь.
Handy Alias позволяет указать синонимы отдельно для словарей, терминов и нод, после чего собрать из них красивый адрес, отражающий положение ноды в дереве категорий.

Работает все это следующим образом:
Прежде всего, необходимо создать словарь, который будет использоваться для формирования пути определенного типа контента.
При создании словаря нужно включить функцию Handy Alias и выбрать тип(ы) контента, для которых термины этого словаря будут использоваться при формировании пути. Кроме того, можно задать синоним для самого словаря (наглядно: форма создания словаря).
Кстати, при включении функции Handy Alias по понятным причинам автоматически отключаются функции «Tags» и «Multiply select».

Далее, при добавлении терминов в словарь, тут же указываем синонимы для них (наглядно: форма создания термина).

Ну и наконец, при создании ноды можно добавлять синоним, если предварительно включить функцию Handy Alias для соответствующего типа контента.
Форма настройки типа контента отныне будет выглядеть вот так.
Форма создания контента, как-то так.

После того, как синонимы заданы, остается настроить паттерны в PathAuto.
Handy Alias позволяет использовать следующие токены для нод:

[vocab-handy-alias]     Синоним, который задается при создании словаря.
[term-handy-alias]      Синоним «верхнего» термина handyalias-словаря. Бесполезный токен, в общем-то.
[term-handy-alias-path] Самое интересное. Если словарь представляет собой дерево, то этот токен вернет синонимы всех терминов снизу до верху, разделенные слэшем.
[node-handy-alias]      Синоним, задаваемый при создании ноды

Для таксономии используются все те же токены, кроме [node-handy-alias].

В качестве приятного бонуса, есть возможность настроить псевдо-расширения .html для заданных типов контента — некоторым нравятся такие анахронизмы.

Если вы дочитали до этого момента, возможно, вам действительно понравилась идея модуля Handy Alias. Я был бы рад, если бы вы присоединились к его тестированию. Для этого нужно пройти вот сюда, скачать его последнюю(!) версию (крутите вниз страницы), постараться найти ошибки и отписаться здесь или там.

Спасибо, пожалуйста.

Комментарии

Аватар пользователя Rishpik Rishpik 25 августа 2010 в 16:29

спасибо за модулью

поставил на денвер.
включил модуль.
включил для типа материала.
включаю для словаря и : warning: Parameter 3 to handyAlias_taxonomy() expected to be a reference, value given in R:\home\test1.ru\www\includes\module.inc on line 483.

Аватар пользователя Stutzer Stutzer 25 августа 2010 в 16:55

какая версия PHP, какой уровень error_reporting стоит?
не могу у себя получить такую же ошибку.

попробуйте в handyAlias.module в строке 184 заменить &$form_values на $form_values (убрать & перед переменной)

Аватар пользователя vgoodvin vgoodvin 17 сентября 2010 в 9:37

"gorr" wrote:
А где ссылка на модуль то?

"Stutzer" wrote:
Для этого нужно пройти вот сюда, скачать его последнюю(!) версию (крутите вниз страницы), постараться найти ошибки и отписаться здесь или там.

Аватар пользователя gorr gorr 17 сентября 2010 в 15:21

Возникла идея небольшая по поводу этого модуля, чтобы использовать апи гугла для перевода на английский термов и заголовков нодов, чтобы не руками значит..
В пару функций модуля вставляем подгрузку скрипта и сам скриптик, обращающийся к гуглу и заполняющий нужное поле (не тестировал его еще, просто пока как идея) :

<?php
/**
 * Implements hook_form_taxonomy_form_term_alter().
 *
 * Add alias fields to the term form.
 */
function handyalias_form_taxonomy_form_term_alter(&$form$form_state) {
  
  
module_load_include('inc''handyalias''handyalias.lib');
  
  
// Get $term as object from $form value
  
$term = (object)$form['#term'];
  
// Get $vocab as object from $form value
  
$vocab = (object)$form['#vocabulary'];

  

// Get handy alias option for this vocabulary
  
$vocab_setings_all variable_get('handyalias_vocab_settings', array());
  
$vocab->handyalias = !empty($vocab_setings_all) ? $vocab_setings_all[$vocab->vid] : 0;
  
  if ( ( !isset(
$form['confirm']) ) &&     // Check if we are not on term delete confirmation page
       
$vocab->handyalias ) &&           // Check if vocabulary allows Handy Alias
       
$vocab->hierarchy <=  ) &&      // Denay multiply hierarchy (Only flat or simple hierarchy structure allowed)
       
$vocab->multiple == ) &&        // Denay multiply term selection
       
$vocab->tags == ) )             // Denay tags
  
{
    
$alias _handyalias_sql('select'$term->tidHANDYALIAS_TYPE_TERM );
    
$form['identification']['name']['#weight'] = -5;
// =================================================
    // Here we add js (NEW!!!)    
    
drupal_add_js(drupal_get_path('module''handyalias') . '/HATranslate.js');
// =================================================    
    // Add textfield for alias
    
$form['identification']['alias'] = array(
     
'#type' => 'textfield',
     
'#title' => t('Term alias'),
     
'#description' => t('For example: <em>track</em> or <em>bus</em>. It can be used as token [term-handy-alias] and [term-handy-alias-path].<br/>NOTE: it`s not a full alias, just a part of it, so don`t use slashes.'),
     
'#default_value' => check_plain($alias),
     
'#access' => user_access('create url aliases'),
     
'#maxlength' => 128,
     
'#weight' => -3,
     
'#element_validate' => array('_handyalias_alias_validate'),
    );
    
$form['identification']['alias_old'] = array(
     
'#type' => 'value',
     
'#value' => check_plain($alias),
    );
    
// Override taxonomy parent options to denay multiply parent term selection
    
$form['advanced']['parent']['#title'] = t('Parent');
    
$form['advanced']['parent']['#multiple'] = FALSE;
    
$form['advanced']['parent']['#size'] = 1;

  }
  elseif ( 

$vocab->handyalias ) {
    
// Print notification if vocabulary set to handy alias but for some reason it have incompatible configuration
    
drupal_set_message(
      
t('Unable to use Handy alias functionality with this vocabulary as it have incompatible configuration. We don`t know how could it happend.<br/>You shouldn`t use "Tags", "Multiply terms" and "Multiply hierarchy" in vocabulary'),
      
'error'
    
);
  }
}

/**
 * Implements hook_form_alter().
 *
 * Add handy alias textfield to node create/edit form
 */
function handyalias_form_alter(&$form$form_state$form_id) {
  
$node = isset($form['#node']) ? $form['#node'] : NULL;
  
// If we have node hash in $form, and Handy Alias feature enabled for this node type
  
if ( isset($form['type']) && isset($form['#node']) && variable_get('handyalias_enable_' $node->type0) ) {
    
// If we have content edit form
    
if ($form['type']['#value'] .'_node_form' == $form_id ) {
// ======================================
    // Here we add js (NEW!!!)
      
drupal_add_js(drupal_get_path('module''handyalias') . '/HATranslate.js');
// ======================================
      // Handy alias textfield
      
$form['handyalias_alias'] = array(
        
'#type' => 'textfield',
        
'#title' => t('Handy alias'),
        
'#description' => t('It can be used as token [node-handy-alias].<br/>NOTE: it`s not a full alias, just a part of it, so don`t use slashes.'),
        
'#default_value' => isset($node->handyalias_alias) ? $node->handyalias_alias '',
        
'#weight' => -4,
        
'#element_validate' => array('_handyalias_alias_validate'),
      );
    }
  }
}
?>
Drupal.behaviors.HATranslate = function(context) {
// the node form
  if($("#edit-title").length) {
    var InElem = $("#edit-title");
        var OutElem = $("#edit-handyalias-alias");
  }
//the term form  
  else if($("#edit-name").length) {
    var InElem = $("#edit-name");
    var OutElem = $("#edit-alias");    
  }
  InElem.blur(function() {
    if(text = InElem.val()) {
          var url = encodeURI('http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q='+text+'&langpair=ru|en');
      $.getJSON(url, function(json) {
            if(json.responseData.translatedText) {
                  OutElem.val(json.responseData.translatedText);
                }
      });      
    }
  });  
       
}

Что думаете?

Аватар пользователя Stutzer Stutzer 17 сентября 2010 в 15:32

Отлчиная идея! Я думал об этом, но поскольку с апи гуглотранслейта было связываться лень... а тут оказывается все не так уж сложно )
Сейчас выложу модуль на орге, а там можно будет и его апгрейдом заняться )

Аватар пользователя gorr gorr 17 сентября 2010 в 16:00

Угу, а я вот думал, что все будет просто, ан нет - getJSON чего-то не захотел в таком виде отправлять запрос, но он еще от версии jquery апи менял, надо проверить, а вот getScript отправил запрос, но ответ гугла отказался воспринимать - пишет invalid label, хотя перевод приходит, вобщем еще повозиться надо будет.

Аватар пользователя gorr gorr 17 сентября 2010 в 18:40

Вобщем так просто не вышло, не допускают браузеры json с чужого сервера без дополнительного параметра jsonp, пришлось воспользоваться как в примерах гугла, причем загрузка скрипта переводчика не захотела работать после загрузки документа, только вместе с ним, пришлось в шаблоне страницы вставить:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("language", "1");
</script>

ну а в файле HATranslate.js такой код:

Drupal.behaviors.HATranslate = function(context) {
  //google.load("language", "1");
// the node form
  if($("#edit-title").length) {
    var InElem = $("#edit-title");
        var OutElem = $("#edit-handyalias-alias");
  }
//the term form  
  else if($("#edit-name").length) {
    var InElem = $("#edit-name");
    var OutElem = $("#edit-alias");    
  }
  InElem.blur(function() {
    if(text = InElem.val()) {
      google.language.detect(text, function(result) {
        if (!result.error && result.language) {
          google.language.translate(text, result.language, "en",
                                    function(result) {
            var translated = document.getElementById("translation");
            if (result.translation) {
              OutElem.val(result.translation);
            }
          });
        }
      });                
    }
  });          
}

Собственно все работает, вставляет красивые переводы само. Спасибо за модуль, правда потестил пока только на форме для нодов.

Аватар пользователя gorr gorr 17 сентября 2010 в 19:06

Из печального - Некоторые слова (заметил например имена собственные, например Аргентина) не хочет переводить, Россия не перевел, а русский пирог - перевел. Аргентинское танго - не перевел. Жаль..
Зато "Бред сивой кобылы" перевело "Bullshit", тут все ок! Smile

Аватар пользователя Stutzer Stutzer 17 сентября 2010 в 19:05

Как вариант запрос делать не с клиента, а с сервера. По идее, должно быть вполне реализуемо. Хотя тут можно получить некоторое зависание, вызванное ожиданием ответа от гугла. Хотя, раз так работает, то отлично )

Аватар пользователя gorr gorr 17 сентября 2010 в 19:08

Да, использовать свой сервер, как прокси можно, но это точно будет с задержкой ощутимой, а не хочется.

Аватар пользователя gorr gorr 17 сентября 2010 в 19:40

Кстати, если пользователю вообще поля не выводить, а слать запрос гуглу с сервера при сабмите ноды и терма, тоже вариант. Можно было бы вынести на страничку настройки модуля выбор - "вручную" или "гугл транслейт" заполнять алиасы.

Аватар пользователя MGMaster MGMaster 18 сентября 2010 в 5:57

Лучше чтобы поле выводил для пользователя и в него автоматом подставлял перевод. А если пользователь не согласен с переводом или гугл не смог перевести, то пользователь сам прописывает что ему нужно.

Аватар пользователя gorr gorr 18 сентября 2010 в 15:15

"MGMaster" wrote:
Лучше чтобы поле выводил для пользователя и в него автоматом подставлял перевод. А если пользователь не согласен с переводом или гугл не смог перевести, то пользователь сам прописывает что ему нужно.

Так у меня уже работает, выше описал как сделал.

Аватар пользователя iehon iehon 20 февраля 2012 в 15:34

отличная идея для модуля. но боюсь ставить, т.к. модуль в проекты на drupal.org не добавлен и не ведется. А ведь с 6ки хочется в будущем переходить на 7ку Smile

Аватар пользователя Stutzer Stutzer 21 февраля 2012 в 15:59

iehona wrote:
отличная идея для модуля. но боюсь ставить, т.к. модуль в проекты на drupal.org не добавлен и не ведется. А ведь с 6ки хочется в будущем переходить на 7ку :)

Боюсь, вы не правы http://drupal.org/project/handyalias

Аватар пользователя Stutzer Stutzer 3 мая 2012 в 5:52

xxandeadxx wrote:
словари можно расширять полями, значения полей доступны в токенах

Разумеется, но как, скажем, поступить в след. ситуации:

Имеем древовидный глубокий словарь.
А (алиас a)
-Б (алиас b)
--С (алиас c)
---Д (алиас d)
----Е (алиас e)

Как для термина Е построить урл вида /a/b/c/d/e
И как для ноды, прикрепленной к термину Е, построить адрес /a/b/c/d/e/node-alias.html

Аватар пользователя Stutzer Stutzer 3 мая 2012 в 5:59

xxandeadxx wrote:
http://xandeadx.ru/blog/drupal/372[/quote]
Похоже, то что нужно, пойду попробую на практике.

Только маленький вопрос: если мы вдруг решаем изменить алиас для термина А с «a» на «а1», нам для этого необходимо поменять путь у всех дочерних терминов или достаточно ограничится только изменением алиаса «а»?

Аватар пользователя xxandeadxx xxandeadxx 3 мая 2012 в 6:06

если под "поменять путь" подразумевается "сгенерировать новые алиасы", то разумеется да. они ведь живут отдельной жизнью

Аватар пользователя Stutzer Stutzer 3 мая 2012 в 6:11

xxandeadxx wrote:
если под "поменять путь" подразумевается "сгенерировать новые алиасы", то разумеется да. они ведь живут отдельной жизнью

Не, не то я имел ввиду. Перестраивать алисы — это само собой.

Перефразирую наглядно:

Возможна ли в D7 из коробки реализация варианта 1?

Аватар пользователя xxandeadxx xxandeadxx 3 мая 2012 в 6:20

1. добавляем словарю поле "Алиас термина"
2. прописываем алиасы для каждого термина
3. прописываем шаблон адресов

[term:parent:parent:parent:parent:parent:field_alias]/[term:parent:parent:parent:parent:field_alias]/[term:parent:parent:parent:field_alias]/[term:parent:parent:field_alias]/[term:parent:field_alias]/[term:field_alias]
Аватар пользователя Stutzer Stutzer 3 мая 2012 в 6:43

Теперь ясно. Как-то это все же смахивает на костыль ) не bulletproof все же. Изменись глубина словаря глубже дозволенного, и все сломается.

Аватар пользователя Stutzer Stutzer 3 мая 2012 в 8:31

По терминам все понятно и работает в принципе.
Проблемы с синонимами для нод.

Имеем словарь category, к нему приаттачено поле field_alias, в котором задается алиас для термина.
При создании шаблонов для ноды нам доступен токен node:field_category, но он возвращает имя термина, а не field_alias, который нам нужен.
Если попытаться написать что-нибудь вроде node:field_category:field_alias получаем ошибку:

Что я делаю не так?