Люди добрые, помгите!
Пока не знай, выйдет ли чего из этого, но пробую - необходимо правило, чтобы вместо адреса 'node/nid' подставлялся адрес 'my_page/my_doc/?id=nid'
прописываю в .htaccess:
Не выходит. Пробовал кучу других вариантов: либо 500, либо не подставляется.
Комментарии
Здравствуйте. Я недавно сталкивался с похожей задачей, нужно было перенаправлять с адресов вида /catalog на адреса вида /index.php?page=catalog
Средствами mod rewrite это не решается, т.к. гет-запросы он попросту игнорирует
Я написал небольшой скрипт на пхп, который считывает гет-запрос и редиректит 301-м редиректом на новые адреса.
Вставил его в index.php, в основной файл друпала. Хоть это и хак ядра, но сработало, индексация сайта не пострадала.
Если вас это устраивает, могу и скрипт скинуть. Хотя там всего 10 строк кода))
Киньте, если не сложно, плиз!
Т.е. именно с /catalog на /index.php?page=catalog редиректит, правильно? А, скажем, заголовок ноды в тизере ссылается все еще на /catalog, правильно понимаю?
Во-первых, mod rewrite никаких запросов не игнорирует, можно в частности работать с условиями по параметрам запроса. И как раз задача
Прекрасно им решается.
А для решения этой задачи
eсть pathauto, и если дополнительно нужны редиректы, то global redirect.
Значит я не знал этого. И решил методом топора) Подскажете, где можно мануалов на эту тему покурить?
Спасибо за отклик! Но в том то и дело, что Друпал не пропускает знаки '?' и '='. Можно разрешить эти символы, в урле они будут как есть, при переходе на страницу в символом '?' отдает 404, т.к., видимо, друпал обрабатывает '?' как параметр. А как отключить обработку, к примеру, только в одном типе материала, не знаю. Вот и хотел схитрить с помощью .htaccess.
Мануал есть здесь. Мне он не помог, т.к. там как раз наоборот делают от того, что нужно мне.
Мануалы там, где они и должны быть: http://httpd.apache.org/docs/current/mod/mod_rewrite.html, http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
Ну и если воспользоваться гуглом, то можно накопать очень много примеров и описаний.
Да, естественно. А вы хотите добиться не такого поведения?
Если вам надо, чтобы придя по старой ссылке, пользователь попал на нужную страницу, тогда действительно можно написать реврайт, только будет дублирование контента и ссылки на сайте будут вести на нормальные адреса, а не на такие, как вы указали.
Как-то так тогда будет выглядеть правило:
RewriteCond %{QUERY_STRING} ^id=%1$
RewriteRule ^(.*)$ /node/$1
Вставить до реврайта для чистых ссылок.
Естественно почитать доку по mod_rewirete и подредактировать при необходимости, т.к. написано по памяти, и не проверялось.
Суть траблы в том, что переношу старый сайт на друпал - 80% путей сайта как раз имеют эти символы, и их необходимо сохранить (именно сохранить, а не редиректнуть).
Вот и думаю, как схитрить!
Т.е. не чтобы пользователь попадал на правильную друпал-стайл страницу, а именно на старый сохраненный путь 'my_doc/?id=1'. Я даже могу импортнуть документы так, чтобы новые ноды в друпале имели тот же nid, что и id старого сайта, но вот как указать старый путь, при этом не редиректом, а как бы подстановкой, я не знаю. А по докам непонятно, делает ли .htaccess именно замену/подстановку адреса, а не реврайт.
Ну и не нашел примера в доках для замены адреса с 'node/nid' на 'my_doc/?id=nid' - только наоборот.
То что я вам выше написал, собственно и не делает редиректа, а переписывает uri вида my_doc/?id=nid в node/nid для внутреннего использования.
Т.е. пользователь перейдя по my_doc/?id=nid, увидит тоже самое, что и по node/nid. При этом это не редирект, т.е. в адресной строке останется my_doc/?id=nid.
Хотя в вашем случае, не надо сохранять старые пути, правильно как раз редиректить на новые адреса, 301 редиректом (добавить [R=301, L] в строку реврайта). Таким образом не будет ненужного дублирования контента. И это как раз правильный способ, с точки зрения поисковика, таким образом вы говорите - этот контент теперь лежит по другому адресу. И все довольны. И поисковик, и пользователи, переходящие по старым линкам и попадающие туда, куда надо.
Да как-то цыкотно 18к посещаемых страниц, и такой риск.
И оптимизатор говорит о том, что тыцы с пиарами будут очень долго передаваться, плюс сапа на этих страницах.
Еще раз Огромное Спасибо! Буду пробовать.
Я ту же задачу решал собственным модулем. Только у меня был 301-й редирект, чтобы поисковики обновились. Это решение хорошо тем, что у меня id != nid, плюс была дополнительная логика при разный значениях в пути.
А как сопоставляли, куда надо редиректить?
У меня была таблица, сформированная при переводе сайта с другого движка.
Блин, не отрабатывает этот код. Я так понимаю, что если url остается неизменным (т.е. ничего не меняется в путях), то в любом случае только условие может быть неправильным, верно?
Пробовал по-разному описывать условия - не хочет и все.
Это не эксперимент, это штатное средство решения таких проблем (http 301), а оптимизаторы очень часто несут откровенный бред, делая умное лицо.
По поводу редиректа, подебажте. Найдите где не проходит условие.
RewriteLogLevel 3
P.S. Замените ^id=%1$ на $id=([0-9]+)$
Прописывая RewriteLog, отдает 500 ошибку. В error_log: "RewriteLog not allowed here"
Прописывал самые разные пути, в т.ч. на папки с правами 777.
"RewriteLog not allowed here" означает, что это прописывается в vhost или на уровне сервера, а не то, что не записать в какую-то папку.
А вообще, нельзя как-то запретить Друпалу обрабатывать '?' как параметр, скажем, только для одного типа материала? Вот реально решение так близко и так далеко!
Про запрет уже понял, что у меня как у пользователя нет прав вроде как вести такие логи.
Это не должно быть проблемой - разработку надо вести не на продакшен сайте, а у себя, в полностью контролируемых условиях.
Это обрабатывает php а не друпал.
Всё же вам уже расписано, как и что делать, только приспособить реврайт под собственные нужды осталось. Вот зачем вы пытаетесь фигню всякую выдумать? Почитайте доку, подправьте под свой случай, пользуйтесь.
Взял шаред, пока не перевел сайт.
Вот в этом и проблема - то, что, казалось бы, должно работать - не работает. Я уже несколько раз сверял код с манами, и на шару подставлял другие синтаксические элементы (перепробовал уже более 50 вариантов).
А есть какое-либо определенное место в коде, где это задается, или таких функций много? Мне кажется, если операторов 'if else' определить тип материала, то должно помочь, нет (сам плохо знаю API)?
А в чём проблема сделать через друпал-то?
$items['my_page/my_doc'] = array(
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
'page callback' => 'my_module_old_site_page',
);
}
function my_module_old_site_page(){
if(isset($_GET['id']) && is_numeric($_GET['id']) && ($node = node_load($_GET['id']))){
return node_view($node);
}else{
return drupal_not_found();
}
}
Это весь код. Не проверял, конечно же - допилить по фффкусу.
Dan, Спасибо за код! Только у меня с ним ничего не изменилось. Как были 2 документа доступны по node/nid, так и есть, а по 'my_page/my_doc/?id=nid' - 404.
Или это только набросок?
Мне уже кажется, что что-то где-то нечисто - ну просто не может сайт не принимать никаких изменений (хотя 500 при ошибках все же отдает) в .htaccess.
Да, это концепт, а не рабочий код. Прикрепи что ты сделал, скажу где ошибка.
Ещё надо чистить кэш меню при работе с меню.
Dan, Спасибо за помощь!
Но может оно того и не стоит, т.к. я в php далеко не силен. Фактически код я изменил только там, где понял, что надо менять: создал модуль (info файл и файл модуля) и прописал в нем твой код:
<?php
function hook_menu(){
$items['newst/news'] = array(
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
'page callback' => 'my_module_old_site_page',
);
}
function my_module_old_site_page(){
if(isset($_GET['id']) && is_numeric($_GET['id']) && ($node = node_load($_GET['id']))){
return node_view($node);
}
else {
return drupal_not_found();
}
}
?>
А мне точно нужно работать с меню? Еще раз уточню: мне нужно, чтобы, к примеру, на этой странице: http://kazanvoyage.ru/node/121 внутренний адрес выглядел вот так: http://kazanvoyage.ru/newst/news/?ID=121, и чтобы на страницу можно было явно попасть по этому адресу.
Если там много кода писать, то может быть и не стоит оно того?
Во первых, вместо hook_menu() надо писать ИМЯМОДУЛЯ_menu()
Во-вторых, прикрепи файлы модуля, дабы можно было посмотреть где ошибка.
Да, тебе надо именно с меню работать )
Изменил имя функции, ничего не изменилось.
Прикрепляю файлы модуля.
Может лучше дать ftp-доступ и админа? сайт тестовый.
Переименовал модуль, поправил твои ошибки, одну свою. Работает.
Dan, огромное человеческое Спасибо (в очередной раз)!
Теперь путь доступен (не редиректит, но теперь он хотя бы отдает реальный id документа по прямому запросу, да еще и со статусом 200ок).
А этого вполне достаточно!