Как-то давным-давно я написал анонс модуля, решающего некоторые проблемы с красивыми адресами, но архив с исходниками в том посте так и не появился, хотя многие его с нетерпением ждали. Причиной тому была его тотальная сырость модуля и отсутствие времени на тот момент.
Не прошло и года, как время и силы таки нашлись, так что прошу любить и жаловать!
Если совсем вкратце, то суть этого модуля можно изложить примерно так:
Особо отъявленные перфекционисты часто негодуют при виде адресов типа такого:
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 позволяет использовать следующие токены для нод:
[term-handy-alias] Синоним «верхнего» термина handyalias-словаря. Бесполезный токен, в общем-то.
[term-handy-alias-path] Самое интересное. Если словарь представляет собой дерево, то этот токен вернет синонимы всех терминов снизу до верху, разделенные слэшем.
[node-handy-alias] Синоним, задаваемый при создании ноды
Для таксономии используются все те же токены, кроме [node-handy-alias].
В качестве приятного бонуса, есть возможность настроить псевдо-расширения .html для заданных типов контента — некоторым нравятся такие анахронизмы.
Если вы дочитали до этого момента, возможно, вам действительно понравилась идея модуля Handy Alias. Я был бы рад, если бы вы присоединились к его тестированию. Для этого нужно пройти вот сюда, скачать его последнюю(!) версию (крутите вниз страницы), постараться найти ошибки и отписаться здесь или там.
Спасибо, пожалуйста.
Комментарии
спасибо за модулью
поставил на денвер.
включил модуль.
включил для типа материала.
включаю для словаря и : 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.
какая версия PHP, какой уровень error_reporting стоит?
не могу у себя получить такую же ошибку.
попробуйте в handyAlias.module в строке 184 заменить &$form_values на $form_values (убрать & перед переменной)
А где ссылка на модуль то?
А слона то я и не заметил..спасибо.
Возникла идея небольшая по поводу этого модуля, чтобы использовать апи гугла для перевода на английский термов и заголовков нодов, чтобы не руками значит..
В пару функций модуля вставляем подгрузку скрипта и сам скриптик, обращающийся к гуглу и заполняющий нужное поле (не тестировал его еще, просто пока как идея) :
<?php
// Get handy alias option for this vocabulary
/**
* 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'];
$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 <= 1 ) && // Denay multiply hierarchy (Only flat or simple hierarchy structure allowed)
( $vocab->multiple == 0 ) && // Denay multiply term selection
( $vocab->tags == 0 ) ) // Denay tags
{
$alias = _handyalias_sql('select', $term->tid, HANDYALIAS_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;
}
$vocab->handyalias ) {elseif (
// 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->type, 0) ) {
// 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'),
);
}
}
}
?>
// 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);
}
});
}
});
}
Что думаете?
Отлчиная идея! Я думал об этом, но поскольку с апи гуглотранслейта было связываться лень... а тут оказывается все не так уж сложно )
Сейчас выложу модуль на орге, а там можно будет и его апгрейдом заняться )
Угу, а я вот думал, что все будет просто, ан нет - getJSON чего-то не захотел в таком виде отправлять запрос, но он еще от версии jquery апи менял, надо проверить, а вот getScript отправил запрос, но ответ гугла отказался воспринимать - пишет invalid label, хотя перевод приходит, вобщем еще повозиться надо будет.
Вобщем так просто не вышло, не допускают браузеры json с чужого сервера без дополнительного параметра jsonp, пришлось воспользоваться как в примерах гугла, причем загрузка скрипта переводчика не захотела работать после загрузки документа, только вместе с ним, пришлось в шаблоне страницы вставить:
<script type="text/javascript">
google.load("language", "1");
</script>
ну а в файле HATranslate.js такой код:
//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);
}
});
}
});
}
});
}
Собственно все работает, вставляет красивые переводы само. Спасибо за модуль, правда потестил пока только на форме для нодов.
Из печального - Некоторые слова (заметил например имена собственные, например Аргентина) не хочет переводить, Россия не перевел, а русский пирог - перевел. Аргентинское танго - не перевел. Жаль..
Зато "Бред сивой кобылы" перевело "Bullshit", тут все ок!
Как вариант запрос делать не с клиента, а с сервера. По идее, должно быть вполне реализуемо. Хотя тут можно получить некоторое зависание, вызванное ожиданием ответа от гугла. Хотя, раз так работает, то отлично )
Да, использовать свой сервер, как прокси можно, но это точно будет с задержкой ощутимой, а не хочется.
на phpclasses.org видел класс для гугло-транслейта
Кстати, если пользователю вообще поля не выводить, а слать запрос гуглу с сервера при сабмите ноды и терма, тоже вариант. Можно было бы вынести на страничку настройки модуля выбор - "вручную" или "гугл транслейт" заполнять алиасы.
Лучше чтобы поле выводил для пользователя и в него автоматом подставлял перевод. А если пользователь не согласен с переводом или гугл не смог перевести, то пользователь сам прописывает что ему нужно.
Так у меня уже работает, выше описал как сделал.
отличная идея для модуля. но боюсь ставить, т.к. модуль в проекты на drupal.org не добавлен и не ведется. А ведь с 6ки хочется в будущем переходить на 7ку
Боюсь, вы не правы http://drupal.org/project/handyalias
в 7-ке этот модуль не нужен
Подскажи, пожалуйста, как решается эта задача в семерке?
словари можно расширять полями, значения полей доступны в токенах
Разумеется, но как, скажем, поступить в след. ситуации:
Имеем древовидный глубокий словарь.
А (алиас a)
-Б (алиас b)
--С (алиас c)
---Д (алиас d)
----Е (алиас e)
Как для термина Е построить урл вида /a/b/c/d/e
И как для ноды, прикрепленной к термину Е, построить адрес /a/b/c/d/e/node-alias.html
http://xandeadx.ru/blog/drupal/372 (первый раз даю ссылку на свой блог!))
если под "поменять путь" подразумевается "сгенерировать новые алиасы", то разумеется да. они ведь живут отдельной жизнью
Не, не то я имел ввиду. Перестраивать алисы — это само собой.
Перефразирую наглядно:
Возможна ли в D7 из коробки реализация варианта 1?
1. добавляем словарю поле "Алиас термина"
2. прописываем алиасы для каждого термина
3. прописываем шаблон адресов
Теперь ясно. Как-то это все же смахивает на костыль ) не bulletproof все же. Изменись глубина словаря глубже дозволенного, и все сломается.
ничто не мешает написать свой токен, это 10 строчек кода. всё же вложенность больше 3-х уровней это редкость
По терминам все понятно и работает в принципе.
Проблемы с синонимами для нод.
Имеем словарь category, к нему приаттачено поле
field_alias
, в котором задается алиас для термина.При создании шаблонов для ноды нам доступен токен
node:field_category
, но он возвращает имя термина, а неfield_alias
, который нам нужен.Если попытаться написать что-нибудь вроде
node:field_category:field_alias
получаем ошибку:Что я делаю не так?
для нод нужен модуль entity tokens из пакета entity api
Отлично, спасибО!