Предистория
После переезда решил навести порядок с отображением сайта. Хотелось чтобы материалы в каталоге статей как и раньше были скомпонованы в одном месте:
Название категории вначале, потом список статей из этой категории, ссылка на все статьи из категории.
Стандартными средствами этого сделать не получилось. Пришлось немного подумать, почитать справочники и решить это средствами JavaScript и JQuery.
Шаг 1. Узнать как делается сейчас
Для начала нужно было узнать каким образом uCoz выводит список на главной странице "Каталога статей"
Для начала в дизайне модуля посмотрел код шаблона, но ничего интересного кроме $BODY$ так и не нашел, значит в это место будет вставляться уже сформированный код, и его не исправить.
Отдельно заинтересовала позиция "Вид материала" , тут описывается вид отдельного блока причем всех сразу.
Выход был один - в каждом блоке написать название категории и ссылку, но заставить их отображаться или скрываться в зависимости от расположения.
Например вид материалов можно записать так:
<div class="mat">
<div class="c_$CID$">
<h2 class="cat_name">$CATEGORY_NAME$</h2></a>
<p>$MESSAGE$</p><a href="$ENTRY_URL$">$TITLE$</a>
<a href="$CATEGORY_URL$" class="clink">ссылка категории</a>
</div>
</div>
Конструкция class="c_$CID$" позволит определить к какой категории относится материал. Если категория имеет ID = 1, то в результате информация в контейнере будет иметь класс с_1
Шаг 3. Тренировка на пробных страницах
Надеюсь не открою большой секрет, что просмотреть код страницы можно через правую клавишу мыши. А дальше в зависимости от браузера:
- исходный код - Opera
- Просмотр HTML-кода - ИЕ
- Исходный код страницы - FireFox
- Просмотр кода страницы - Chrome
Из всего кода нам понадобиться только часть относящаяся к показываемым элементам.
Второй способ получения кода - сохранить страницу как HTML на жестком диске.
В любом случае желательно оставить только "полезную" информацию, а остальную разметку страницы удалить.
вот что получилось у меня
<html>
<head>
<title>Categories</title>
</head>
<body>
<div class="hidden"> <!-- Тут начало категорий -->
<!-- Один из Блоков с информацией -->
<div class="mat"><div class="c_2"> <span class="name">Kat 2</span>
<p>Text #1 of this category #2</p><a href="#">ссылка</a><br />
<a href="#" class="clink">ссылка категории</a><br />
</div></div>
<!--- Конец блока -->
<div class="mat"><div class="c_3">
<span class="name">Kat 3</span>
<p>Text #1 of this category #3</p><a href="#">ссылка</a><br />
<a href="#" class="clink">ссылка категории</a><br />
</div></div>
<div class="mat"><div class="c_1">
<span class="name">Kat 1</span>
<p>Text #1 of this category #1</p><a href="#">ссылка</a><br />
<a href="#" class="clink">ссылка категории</a><br />
</div></div>
<div class="mat"><div class="c_4">
<span class="name">Kat 4</span>
<p>Text #1 of this category #4</p><a href="#">ссылка</a><br />
<a href="#" class="clink">ссылка категории</a><br />
</div></div>
<div class="mat"><div class="c_3">
<span class="name">Kat 3</span>
<p>Text #2 of this category #3</p><a href="#">ссылка</a><br />
<a href="#" class="clink">ссылка категории</a><br />
</div></div>
<div class="mat"><div class="c_2">
<span class="name">Kat 2</span>
<p>Text #2 of this category #2</p><a href="#">ссылка</a><br />
<a href="#" class="clink">ссылка категории</a><br />
</div></div>
</div> <!-- Конец категорий -->
</body>
</html>
Шаг 4. Знакомство с jQuery
Дальнейшую судьбу скрипта определили несколько событий:
- просмотр видео про jQueryот Дениса Хомича
- книга Бер Бибо и Иегуда Кац "jQuery. Подробное руководство по продвинутому JavaScript"
- поддержка jQuery системой uCoz
По совету Дениса Хомича попробовал выделить разные классы (индикатором выделения служило CSS свойство background-color):
- с_1, с_2, с_3, - содержимое, относящееся к разным категориям
- mat - отдельные блоки
- cat_name - название категории
- clink - ссылки
- выделить первый (последний) элемент в категориях
- выделить все элементы кроме первого (последнего)
$('.c_1').css('background-color','#FC0')
$('.c_2').css('background-color','#FC0')
$('.c_3').css('background-color','#FC0')
$('.mat').css('background-color','#FC0')
$('.clink').css('background-color','#FC0')
Теперь, когда узнали как отбираются и выделяются элементы, можно подумать над функциональностью (вернее над тем как будет работать) будущего сценария (скрипта):
- скопировать содержимое в буфер и скрыть от просмотра. Для пользователей отключивших поддержку сценариев страница будет в нетронутом виде.
- посчитать количество записей на странице, и число веденных категорий, в самом неприятном случае у каждой записи может быть своя категория.
- отсортировать записи в буфере по ID категории.
- вывести полученный массив на странице
Шаг 5. Объединение сценариев JavaScript и jQuery
Собственно говоря достаточно заключить весь скрипт в теги <script type="text/javascript"> </script>.
Буфером будет массив - Array, размер массива будет равен количеству записей, для этого определим переменные, в другом массиве определяем номер категории, соответствующий материалу
var nv = $('.mat').size(); // Число записей на странице
var nc = 1;
var par = new Array(nv); //html код материала
var numCat = new Array (nv);
var category = new Array(nv); //номер категории материала
Работа с массивами - копирование, сортировка, вывод на экран - выполняется оператором цикла for() и оператором сравнения if().
// вычисляем число категорий, задаем стили для разных элементов в категории
for (var i = 0; i < nv; i++)
{
var cx, tcx;
/* пробегаемся про всем возможным категориям
и записываем число записей в массив*/
cx = '.c_'+ i;
numCat [i] = $(cx).size();
nc = (numCat [i] != 0)? i: nc;
/*Находим первое упоминание названия категории (класс name)
и скрываем все остальные записи*/
tcx = cx + ' .name:not(:first)';
$(tcx).attr('style','display:none');
/*Находим последнее упоминание ссылки на все материалы
категории (класс clink) и скрываем все остальные записи*/
tcx = cx + ' .clink:not(:last)'
$(tcx).attr('style','display:none');
}
nc +=1; // число категорий
/*копируем полученное html содержимое в буфер*/
for (var i = 0; i < nv; i++)
{
var tx;
tx = '.mat:eq('+ i + ')'
par [i] = $(tx).html();
/*Определяем к какой категории принадлежит материал
и записываем ее ID в другой массив*/
for (var j=0; j < nc; j++)
{
var dx;
var nu;
dx = tx + ' .c_'+ j;
nu = $(dx).size();
if (nu != 0 )
{
category [i] = j;
} // enf if
}//end for (j)
} // end for (i)
Сортировку необходимо проводить по номеру категории и при этом менять содержимое сразу в категориях и в материалах.
Вывод содержимого можно выполнить с помощью document.write() в том блоке в котором стоит скрипт
text = '';
for (var i = 0; i < nv; i++)
{
text+= '<div class="mat">' + par [i] + '<br>' + '</div>';
}
document.write(text);
Шаг 6. Варианты усовершенствования кода
предложенный в листингах код далек от совершенства. для более продвинутых можно внести изменения
- вывод выполнять в нужном месте с помощью jQuery функции append(), стерев содержимое remove().
- для содержимого задать новый объект, и сделать массив объектов.
- применить более продвинутые способы сортировки
Посмотреть работу скрипта на
сайте