Сезон навигации открыт

Автор статьи: Артемий Ломов ©
Сайт Автора: webz.ru
E-mail Автора: artemy@lomov.ru
Дата публикации: 20.12.2005

 Гипертекстовые ссылки — неотъемлемый элемент любой web-страницы и основа основ идеологии Всемирной Паутины. Множество ссылок, область действия которых лежит в пределах одного сайта, составляет систему навигации последнего.
Система навигации позволяет установить взаимосвязи между страницами сайта, логически объединить разрозненные HTML-документы, придать проекту целостность.

В идеале, согласно Я. Нильсену, навигация сайта должна в любой момент предоставлять посетителю четкие ответы на три вопроса: «Где я нахожусь?», «Где я уже был?» и «Куда я могу отсюда пойти?».

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

В то же время, система реальных взаимосвязей между страницами web-ресурса не всегда является зеркальным отражением нарисованного на бумаге дерева логической структуры — зачастую устройство средств навигации намного сложнее условной древовидной схемы, ибо на большинстве сайтов навигация предусматривает значительное количество неосновных, вспомогательных связей. Все подобные ссылки, как правило, избыточны, но благодаря ним можно существенно увеличить степень интерактивности сайта, удобство его использования. Здесь уместно вспомнить известное «правило двух щелчков» — крайне желательно, чтобы переход между двумя любыми страницами можно было осуществить при помощи всего двух нажатий на кнопку мыши. Реализовать такое на сайтах с многоуровневой иерархией древовидной структуры без вспомогательных связей порой бывает принципиально невозможно.

По волнам гипертекста
Система навигации любого сколько-либо сложного web-проекта при ближайшем рассмотрении выявляет свою неоднородность.

Все средства навигации можно подразделить на внутренние и внешние (по отношению к данному сайту). Внутренняя навигация представлена гиперссылками, размещенными на страницах самого web-ресурса, тогда как навигация внешняя, «неофициальная», сопряжена со свободой перемещений, предоставляемой пользователю программой-клиентом, то есть браузером. Так, кнопка «Назад» — безусловный лидер, ее нажимают намного чаще, чем соседнюю «Вперед». Помимо двух этих кнопок, к средствам внешней навигации можно отнести адресную и статусную строки браузера, а также заголовок его окна.

Внутренняя навигация неоднородна сама по себе. Первое, на что обращает внимание посетитель — панель навигации, где представлены ссылки на базовые разделы сайта. Это «парадная», магистральная, основная часть системы навигации. Но на страницах сайта пользователь может встретить и вспомогательные элементы навигации — например, ссылки с надписями «К предыдущему подразделу», «К следующему подразделу», «На уровень вверх», «В начало» и т. д.

Что нужно сделать для того, чтобы система навигации создаваемого сайта удалась на славу? Во-первых, конечно же, необходимо следовать общепринятым правилам хорошего тона, которых мы коснемся в начале этой статьи. Во-вторых, не мешало бы облегчить труд по поддержке сайта себе любимому, дабы не возникало соблазна нарушить означенные правила. Один из возможных способов рассмотрим чуть ниже, во второй части материала.

Проектируем внутреннюю навигацию
В случае, если предстоит разработка довольно сложного сайта, лучше заранее продумать его логическую структуру, выявить главное и второстепенное, разложить все по полочкам, в конце концов, нарисовать на листе бумаге ту самую схему в виде дерева. Она и послужит отправной точкой для создания системы внутренней навигации.

Основных разделов (ветвей, отходящих от корня дерева) на сайте в идеале должно быть не более семи. Только в этом случае пользователь сможет быстро привыкнуть к расположению кнопок в панели навигации. Если же количество основных разделов существенно «зашкаливает» за 7, логическую структуру, очевидно, следует пересмотреть. Возможно, потребуется какие-либо самостоятельные разделы сделать подразделами одной большой темы.

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

Если в качестве кнопок навигации используются графические изображения, то их требуется обязательно снабжать содержательными alt-текстами. В случае использования карт ссылок, реализуемых при помощи тэга <map>, требуется обязательно дублировать навигационную панель текстовой строкой — не все браузеры поддерживают карты ссылок.

Многие web-разработчики облегчают свои заботы, используя технологию SSI, в частности, для организации меню навигации. К сожалению, очень часто бывает, что в таких меню встречаются ссылки, ведущие на ту же самую страницу, на которой находится ссылка. Это очень грубый недочет, разрушающий логику построения сайта, и от него нужно обязательно избавляться. Кстати говоря, отказ от SSI в данном случае вовсе не обязателен — SSI поддерживает директивы обработки условий, при помощи которых можно проверить, какая страница запрошена пользователем.

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

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

Основное меню навигации, как правило, заметно сразу, и его оформление может быть достаточно вольным (в разумных пределах, конечно). А что касается выбора цветов текстовых ссылок в остальной части сайта, то должно существовать четкое разделение всех ссылок на просмотренные и непросмотренные, причем у пользователя не должно возникать неопределенности, возможности двоякого толкования. Лучше всего обойтись цветами по умолчанию — синий для непросмотренных ссылок и пурпурный половинной яркости — для просмотренных. Если это невозможно с эстетической точки зрения, просмотренные ссылки должны явным образом свидетельствовать о своей «отработанности», к примеру, иметь менее насыщенный цвет, чем непросмотренные, или цвет, более близкий к цвету основного текста или фона страницы, чем у непросмотренных ссылок.

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

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

На страницах любого web-ресурса неизбежно присутствуют как внутренние, так и внешние ссылки, ведущие на другие сайты. Такова идеология Всемирной паутины — все сайты в ней взаимосвязаны. Для внешних ссылок, например, на дружественные ресурсы, на сайтах, как правило, отводится обособленный раздел. В случае же, когда в тексте внутренние ссылки перемежаются с внешними, нужно снабжать последние каким-либо значком с целью однозначно дать пользователю понять, что данная ссылка ведет во внешнюю среду.

Окна во внешний мир
Принудительно открывать внешние ссылки в выпадающих новых окнах — дурной тон. Разработчики пытаются таким образом задержать пользователя у себя на сайте. Но следует помнить, что пользователь всегда уйдет с сайта, если ему там не нравится, и вернется вновь, если сайт ему нужен, и никакие хитроумные ухищрения здесь не помогут. Завоевывать признание нужно честно.

Выпадающие окна, в особенности, открываясь во весь размер экрана, могут напрочь сбить не слишком опытного пользователя с толку. В них, кроме всего прочего, не работает кнопка «Назад». Пользователю нужно дать возможность выбора — пусть сам в случае надобности, удерживая (в MSIE), открывает ту или иную ссылку в новом окне. Конечно, существуют избранные случаи, когда принудительное открытие новых окон действительно повышает удобство пользования — например, если по щелчку на уменьшенной копии изображения на странице большого иллюстрированного каталога в новом окне открывается полноэкранная версия картинки. Но во всех подобных ситуациях необходимо заранее предупреждать пользователя, что те или иные ссылки открываются в новых окнах, иначе может произойти конфуз.

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

MySite.Ru > Проекты > Статьи > О навигации > Глава 5

Четыре первые надписи выделены подчеркиванием в знак того, что они являются ссылками на страницы с оглавлениями соответствующих разделов. Удобно, не так ли?

Не забывая о навигации внешней
Не следует пренебрегать стандартными элементами интерфейса браузеров. Как уже отмечалось, особенно часто используется кнопка «Назад». Намеренно блокировать работу этой кнопки — дурной тон. Нужно по возможности воздержаться также и от использования технологий, нарушающих логику работы кнопки «Назад» (например, фреймов, Flash-заставок и анкеров, т. е. ссылок внутри одной страницы).

URL страницы может дать много информации, если каталоги и файлы, составляющие сайт, названы разработчиками «говорящими» именами в соответствии с логикой построения сайта. Согласитесь, нижеследующий URL несет достаточно сведений о текущей странице:

http://www.mysite.ru/projects/articles/navigation/chapter05.html

Помимо чисто справочной роли, URL такого вида вполне может использоваться для передвижения по сайту. Посетитель, сократив этот адрес, скажем, до вида «http://www.mysite.ru/projects/», сможет при помощи одного щелчка мыши попасть на страницу оглавления раздела «Проекты», которая находится тремя уровнями выше! Изменив «chapter05.html» на «chapter03.html», посетитель сможет перейти к одной из предыдущих глав, не пользуясь для этого внутренней навигацией сайта.

Статусная строка браузера тоже может принести немало пользы. При наведении курсора мыши на любую гиперссылку, размещенную на загруженной странице, в статусной строке браузера выводится URL того объекта, на который ведет данная ссылка. Это очень ценная информация: по ней посетитель может узнать, является ли ссылка внешней или внутренней, на объект какого типа она указывает (к примеру, на обычную HTML-страницу, графическое изображение или ZIP-архив) и т. п. К сожалению, некоторые недальновидные разработчики используют статусную строку не по назначению — например, выводят в ней при помощи JavaScript различные надписи вроде «Добро пожаловать!», что является, в сущности, бесполезной информацией, приносящей в данном контексте только вред.

Чрезвычайно важное значение при ответе на вопрос «Где я нахожусь?» имеет заголовок окна браузера, который, как известно, отображает информацию, содержащуюся в элементе <title>…</title> HTML-кода web-страницы. Грамотное составление содержимого этого элемента — большая наука. На главной странице, помимо названия сайта, в заголовке окна должно фигурировать сверхкраткое описание ресурса, которое, кстати говоря, весьма позитивно отражается на релевантности страницы при попытке найти слова, содержащиеся в контейнере , с помощью поисковых машин. Пример грамотного заглавия для главной страницы сайта:

MySite.Ru: сайт для web-разработчиков всех уровней

На внутренних страницах содержимое заглавия должно отражать положение того или иного подраздела в иерархической структуре сайта. Для вышеприведенного URL содержимое элемента <title>…</title> может выглядеть следующим образом:

Глава 5 – О навигации - Статьи - Проекты - MySite.Ru

Следует обратить внимание на то, что в заглавии внутренней страницы сайта непременно должны присутствовать как название самой страницы, так и название сайта в целом, причем название страницы лучше всего размещать на первом месте, поскольку, скажем, в «Панели задач» Windows отображается кнопка, содержащая лишь первые несколько символов заголовка окна, и, если открыто несколько страниц одного и того же сайта, идентифицировать то или иное окно по кнопке в «Панели задач» будет значительно легче.

Два лаптя по карте
Как правило, средний web-ресурс информационной направленности на начальном этапе своего развития состоит из небольшого количества страниц — обычно их насчитывается не более нескольких десятков. Заложенная логическая структура ясна и понятна, так что, казалось бы, незачем обременять себя заботой о таких «отвлеченных» вещах, как карта сайта.

Но вот проходит год, два, ресурс развивается, контент пополняется, и количество новых страниц растет как на дрожжах. В какой-то момент web-мастер проекта понимает, что даже ему самому стало трудно ориентироваться в материалах сайта, не говоря уже о посетителях. Но как быть? Создание карты сайта, состоящего, скажем, из трехсот страниц, способно отнять целый день. От осознания подобного фронта работ весьма немудрено прийти в ужас.

Нельзя ли каким-то образом автоматизировать процесс создания карты сайта? Давайте проанализируем. Карта сайта — всего лишь маркированный список с несколькими уровнями вложенности, элементами которого являются названия (а иногда и описания) тех или иных разделов и подразделов web-ресурса, оформленные как ссылки на соответствующие страницы.

Информация о названии HTML-документа должна содержаться в составе его самого, точнее, в контейнере <title>…</title>. Нередко из содержимого кода HTML-страницы удается вычленить и ее описание — порой разработчики снабжают заголовки документов тэгом <meta name="description" content="…"> в надежде увеличить релевантность сайта при поиске. А коли так, нам достаточно списка имен файлов всех страниц сайта — формирование ссылок можно доверить несложному скрипту. Еще нам необходимо каким-либо образом задать иерархию разделов сайта и последовательность их расположения в карте сайта.

Пользователям Windows сформировать список имен файлов web-страниц поможет команда dir. Вот пример синтаксиса команды, выполнение которой приведет к созданию файла source.txt, где будут отражены названия всех файлов с расширениями htm, html, shtml и xhtml из текущей папки, включая все подкаталоги:

dir *.*htm* /l /s /b > source.txt

Небольшая правка, включающая в себя, в основном, операции замены и вырезания/вставки, позволит избавиться от абсолютного пути к текущей папке (следует оставить лишь относительные пути, обычные для гиперссылок) и расположить имена файлов в соответствии с последовательностью, принятой на сайте. Чем более «говорящими» являются названия файлов, тем быстрее удастся рассортировать их. Чтобы показать иерархию подразделов, условимся использовать пробельные символы в начале строк: имя файла без пробелов — высший уровень иерархии (корень дерева, индексная страница), один пробел перед именем файла — основные разделы сайта, два пробела — подразделы первого уровня и т. д. Нужно обратить внимание, чтобы не было «скачков» через несколько уровней вложенности: если под именем файла индексной страницы, приведенным без пробелов, находится имя документа, соответствующего какому-нибудь подразделу, затерянному в дебрях, с тремя пробелами перед именем — это явная ошибка логической структуры сайта, которую нужно исправить.

Если написать скрипт, подобный приведенному ниже, то вся рутина закончится на этапе создания файла source.txt по правилам, означенным в предыдущем абзаце, что даже в случае нескольких сотен страниц отнимает от силы полчаса.

Итак, скрипт для формирования карты сайта:

# mkmap.pl - скрипт для генерации карты сайта
# в соответствии с существующей логической структурой
# (C) А. Ломов, 2003

# Открываем файл source.txt для чтения как поток SOURCE.
# В случае отсутствия такого файла выводим сообщение об ошибке.
if (-e 'source.txt')
{
  open(SOURCE, "source.txt");
}
else
{
  print "MkMap: Не удается обнаружить файл source.txt.\n";
  exit(0);
}

# Путь к каталогу, в котором следует искать файлы для вычленения
# названий и описаний документов, задается пользователем в
# командной строке. В случае, если путь не задан, подразумевается
# текущий каталог.
$path = shift(@ARGV);

# Добавляем в конец пути обратный «слэш», если путь не равен
# пустой строке и в конце его еще нет «слэша».
if (($path ne '') && (substr($path, -1) ne '\'))
{
  $path = $path . '\';
}

# Выходной файл – sitemap.html. Там по окончании работы скрипта будет
# содержаться готовая карта сайта.
open(SITEMAP, '>sitemap.html');

# Первая строчка выходного файла - открывающий тэг
# маркированного списка.
print SITEMAP "<ul>\n";

# Устанавливаем в 0 значение переменной, назначение
# которой будет пояснено чуть ниже.
$lastspaces = 0;

# Цикл выполняется, покуда «есть порох в пороховницах» -
# построчно читаем файл source.txt.
while ($filename = <SOURCE>)
{
  chomp ($filename);

# Цель нижеслежующего цикла – выявить количество пробелов перед
# очередным именем файла, а также запись в переменную $filename
# «очищенного» от пробелов имени файла.
  for($spaces = 0; $spaces <= length($filename); $spaces++)
  {
    if (substr($filename, $spaces, 1) ne ' ')
    {
    $filename = substr($filename, $spaces);
    last;
    }
  }

# Переменная $lastspaces отражает количество пробелов, найденных
# в предыдущий раз. В переменной $spaces содержится количество
# пробелов, найденных в начале строки с именем файла в этот раз.
# Переменная $diff призвана хранить разность этих показаний.   $diff = $lastspaces - $spaces;

# Если в этот раз пробелов стало на один больше, добавляем еще
# один уровень вложенности в список путем вывода дополнительного тэга
#
    . В случае, если новых пробелов стало больше одного,
    # предупреждаем об ошибке логической структуры. Несмотря на ошибку,
    # часть карты сайта сформировано и доступно для анализа в файле
    # sitemap.html, что не является, в сущности, недостатком скрипта -
    # ведь не до конца сгенерированная карта поможет быстро установить
    # место ошибки.
      if($diff < 0)
      {
        if($diff < -1)
        {
            print "MkMap: Ошибка логической структуры - нет одного или
          нескольких уровней иерархии.\n";
          exit(0);
        }
        print SITEMAP "<ul>\n";
      }

    # В случае, если пробелов стало меньше, выводятся закрывающие тэги
    #
в количестве, соответствующем числу пробелов. Вероятно, этот
# цикл можно каким-то образом объединить с предыдущим, и вообще
# сделать все более оптимальным и элегантным, но мы пишем скрипт для
# себя, и наша цель – сэкономить свое рабочее время, а не процессорное
# время компьютера (которого и без того тратится очень немного).
  if($diff > 0)
  {
    for($j = 0; $j < $diff; $j++)
    {
      print SITEMAP "</ul>\n";
    }
  }

# Организуем новую переменную $file, где будем хранить
# абсолютный путь к файлу HTML-страницы, который нужно
# проанализировать. Как вы помните, в файле source.txt
# находятся лишь относительные пути.
  $file = $filename;

# Прибегаем к помощи регулярных выражений. Убираем возможные
# символы «\» и «/» из начала строки.
  $file =~ s/^\//;
  $file =~ s/^\///;

# Заменяем все прямые «слэши» на обратные – в результате скрипт
# будет нечувствителен к привычкам пользователя.
  $file =~ s/\//\/g;

# Присоединяем к началу строки абсолютный путь к каталогу, взятый,
# напомним, из параметра командной строки.
  $file = $path . $file;

# В случае обнаружения файла $file считываем из него всю
# информацию в виде одной большой строки $info.
  if (-e $file)
  {
    @filestats = stat($file);
    $filesize = $filestats[7];
    open(FILEINFO, $file);
    sysread (FILEINFO, $info, $filesize);
    close(FILEINFO);
  }

# Убираем из строки $info все символы новой строки и
# заводим новую переменную $descr. В строке $info впоследствии
# будет храниться только содержимое контейнера <title>...</title>,
# а переменная $descr будет представлять собой описание, взятое
# из метатэга.
  $info =~ s/\n//g;
  $descr = $info;

# Удаляем все, что было до <title>...
  $info =~ s/^.+<title>//;

# ...и все, что будет после </title>
  $info =~ s/<\/title>.+$//;

# Это регулярное выражение предназначено для иерархических
# заголовков, рассмотренных в начале статьи. Отрезается все,
# что следует за первым встретившимся сочетанием « -», включая
# его само.
  $info =~ s/ -.+//;

# Удаляем все, что было до «meta name="description" content="»...
  $descr =~ s/^.+<meta name=\"description\" content=\"//;

# ...и все, что будет после первой встретившейся кавычки
  $descr =~ s/\".+//;

# Заменяем в $filename все обратные «слэши» на прямые, как принято
# в гиперссылках.
  $filename =~ s/\/\//g;

# Генерируем пункт списка – тэг <li> и ссылку на файл.
  print SITEMAP "<li><a href=\"$filename\">";

# Если $info не содержит угловых скобок и слэшей, а также не
# является пустой строкой, есть основания полагать, что эта
# строка содержит именно то, что нам требуется. Оформляем значение
# переменной $info как ссылку. В противном случае оформляем как
# ссылку словосочетание «Untitled document» - возможно, заголовка
# окна в документе попросту нет.
  if (($info !~ /[<>\/\"]/) && ($info ne ''))
  {
    print SITEMAP "$info</a>\n";

# В случае, если строка $descr также не пустая и не содержит угловых
# скобок и слэшей, под ссылкой помещаем описание документа,
# набранное чуть меньшим кеглем (применяем тэг <small>).
    if (($descr !~ /[<>\/\"]/) && ($descr ne ''))
    {
      print SITEMAP "<br><small>$descr</small>\n";
    }
  }
  else
  {
    print SITEMAP "(Untitled document)</a>\n";
  }

  $lastspaces = $spaces;
}

# В конце работы добавляем нужное количество закрывающих тэгов </ul>.
for($j = 0; $j < $lastspaces; $j++)
{
  print SITEMAP "</ul>\n";
}

print SITEMAP "</ul>";

# Финишная прямая.

close(SITEMAP);
close(SOURCE);

print "MkMap: работа успешно завершена. См. файл sitemap.html\n";

exit(0);

Этот сценарий можно было бы усовершенствовать, например, заставив его модифицировать ссылки вспомогательной навигации на страницах сайта в соответствии с заданной в файле source.txt структурой. Но статья и так получилась большой, так что ограничимся здесь «базовой версией».

Дальнейшее администрирование карты сайта несложно — достаточно лишь не забывать добавлять имена файлов вновь созданных разделов в файл source.txt (или, в нашем стиле, написать скрипт, который бы делал это автоматически).