Внешние ссылки в новом окне, средствами Друпала и jQuery.

Аватар пользователя Ромка Ромка 27 июня 2007 в 17:48

В этом сообщении рассказано о модуле External Links, который позволяет сделать так, чтобы все внешние сслыки, даже те, у которых не установлен атрибут "target=_blank", открывались во внешнем окне. Решение простое, но, на мой взгляд, не очень изящное, ведь приходится устанавливать сторонний модуль для выполнения задачи, которая легко решается с помощью библиотеки jQuery, встроенной в Друпал.

Js-script позаимствован мною отсюда, я только его немного доработал. Просто скопируйте и вставьте в любое место шаблона (в node.tpl.php, например) один из следующих вариантов кода.

0. Внимание! Все нижеперечисленные примеры работают с библиотекой jQuery 1.1.2 от 2007-02-28. С Друпалом 5.1 поставляется более старая версия этой библиотеки, по этому нужно скачать с jquery.com последнюю её версию, переименовать в jquery.js и скоприровать в папку misc.

1. Все внешние ссылки на странице открываются в новом окне:
drupal_add_js("\$(document).ready(function(){\$(\"a[href^=http:]\").each(function(){if(this.host!=\"" . $_SERVER['HTTP_HOST']. "\"){\$(this).attr(\"target\",\"_blank\");}});});", "inline");
?>

2. В новом окне открываются все ссылки из слоя "node", то есть из слоя с контентом, а не из меню, футера итп:
drupal_add_js("\$(document).ready(function(){\$(\"div.node a[href^=http:]\").each(function(){if(this.host!=\"" . $_SERVER['HTTP_HOST']. "\"){\$(this).attr(\"target\",\"_blank\");}});});", "inline");
?>

3. В новом окне открываются все ссылки, плюс справа от внешних ссылок отображается иконка, символизирующая новое окно:
drupal_add_js("\$(document).ready(function(){\$(\"a[href^=http:]\").each(function(){if(this.host!=\"" . $_SERVER['HTTP_HOST']. "\"){\$(this).attr(\"target\",\"_blank\");$(this).after(\"\");}});});", "inline");
?>, где 1.jpg – и есть та самая иконка.

4. В новом окне открываются все ссылки, плюс внешние ссылки выделяются особым стилем:
drupal_add_js("\$(document).ready(function(){\$(\"a[href^=http:]\").each(function(){if(this.host!=\"" . $_SERVER['HTTP_HOST']. "\"){\$(this).attr(\"target\",\"_blank\");$(this).addClass(\"extLink\");}});});", "inline");
?>, где extLink – описание класса, который применится ко всем внешним ссылкам.

Имхо, такой вариант значительно удобнее чем использование внешнего модуля, как минимум он позволяет четко указать где нужно заменять ссылки, а где нет. Например, ссылки в футере этой страницы внешние, но иконки со стрелками, которые расставил модуль, на мой взгляд, там не к месту. Кроме того модуль дает некоторую нагрузку на сервер, а предложенное мной решение выполняется целиком на стороне клиента Lol

P.S. Голый код, который не обязательно использовать в Друпале, выглядит так:

$(document).ready(function(){
$(function(){$("a[href^=http:]").each(function(){if(this.host!="example.com")$(this).attr("target","_blank")})})
});

?>

Тэги php использованы только для того чтобы подсветить синтаксис, иначе форум не корректно порежет этот пример. Example.com нужно заменить на свой хост.

P.P.S По мотивам вот этой статьи привожу пример того, как сделать так, чтобы юзеры сами могли выбирать открывать внешние ссылки в новом окне или в текущем.

1. Предварительная подготовка.

Необходимо включить модуль Profile, который входит в ядро пятого друпала, и с его помощью добавить в профиль пользователя поле типа checkbox, назовем его "profile_ext_links_in_new_window" и дадим ему заголовок "Открывать внешние ссылки в новом окне".

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

2. Открывать внешние ссылки в новом окне или нет?

В page.tpl.php в тэгах < head > < /head > после подключения библиотеки jquery вставьте такой код:
global $user;
$req = db_query("SELECT v.value FROM {profile_values} v INNER JOIN {profile_fields} f
ON f.fid = v.fid WHERE f.name = 'profile_ext_links_in_new_window' AND uid = " . $user->uid);
$res = db_fetch_object($req);
if($res->value)
{
?>