Урок 3. Первый шаг. Раздел новостей

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

Создать календарь средствами одного HTML - задача достаточно нетривиальная, к тому же код получится очень громоздким. Сейчас мы расскажем, как легко это сделать на Parser. Приступаем.

Все файлы, относящиеся к разделу новостей, будем размещать в разделе /news/, что было указано нами в файле sections.cfg. Для начала создадим там (!) файл auto.p. Да, файлы auto.p можно создавать в любом каталоге сайта. Однако при этом надо иметь в виду, что функции, описанные в auto.p разделов, будут явно доступны только внутри этих разделов. Ни к чему загромождать корневой auto.p функциями, которые нужны для одного раздела. Логичнее вынести их в отдельный файл, относящийся именно к этому разделу.

Еще одно замечание: если в 
auto.p раздела переопределить функцию, ранее описанную в корневом auto.p, то будет исполняться именно эта переопределенная функция. Сработает механизм виртуальных функций, описанный в предыдущем уроке.

Итак, в 
auto.p раздела news пишем такой код:

@calendar[]
$calendar_locale[
   $.month_names[
         $.1[Январь]
         $.2[Февраль]
         $.3[Март]
         $.4[Апрель]
         $.5[Май]
         $.6[Июнь]
         $.7[Июль]
         $.8[Август]
         $.9[Сентябрь]
         $.10[Октябрь]
         $.11[Ноябрь]
         $.12[Декабрь]
   ]
   $.day_names[
         $.0[пн]
         $.1[вт]
         $.2[ср]
         $.3[чт]
         $.4[пт]
         $.5[сб]
         $.6[вс]
   ]
]

<style>
   .calendar th, .calendar td {text-align: center;}
   .calendar .weekday {background: silver;}
   .calendar .week5day, .calendar .week6day {color: red;}
   .calendar .today {font-weight: bold;}
</style>
$now[^
date::now[]]
$days[^
date:calendar[rus]($now.year;$now.month)]
<table class="calendar">
   <tr>
      <th colspan="7">
         
<b>$calendar_locale.month_names.[$now.
month]</b>
      </th>
   </tr>
   <tr>
   
   ^for[i](0;6){
         <th class="weekday week${i}day">
            $calendar_locale.day_names.$i
         </th>
      }
   </tr>
   
^days.
menu{
      <tr>
         ^
for[i](0;6){
            ^if($days.$i){
               <td class="^if($days.$i == $now.day){today}">
                  $days.$i
               </td>
            }{
               <td></td>
            }
         }
      </tr>
   }
</table>

Мы определили функцию
calendar, которая создает HTML-код календаря. Получился довольно громоздкий код, но ведь и задачи, которые мы ставим перед собой, тоже усложнились.

Самая объемная часть кода, начинающаяся с определения
$calendar_locale, оказалась незнакомой. В приведенной структуре мы определяем какие-то данные для календаря, напоминающие таблицу. То, что определено как $calendar_locale, в терминологии Parser называется «хеш», или ассоциативный массив. Зачем он нужен, можно сказать, просто бегло просмотрев код примера: здесь мы сопоставляем русское написание месяца с его номером в году (3 - март), название дня недели - с его порядковым номером, а также связываем шестнадцатеричное значение цвета с некоторым числом. Теперь идея хешей должна проясниться: они нужны для сопоставления (ассоциативной связи) имени с объектом. В нашем случае мы ассоциируем порядковые номера месяцев и дней с их названиями (строками). Parser использует объектную модель, поэтому строка тоже является объектом. Нам несложно получить порядковый номер текущего месяца, но намного нагляднее будет вывести в календаре «ноябрь» вместо 11 или «пн» вместо 1. Для этого мы и создаем ассоциативный массив.

В общем виде порядок объявления переменных-хешей такой:

$имя[
   $.ключ[значение]
]

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

После определения хеша мы видим уже знакомую переменную
now (текущая дата), а вот дальше идет незнакомая конструкция:

$days[^date:calendar[rus]($date.year;$date.month)]

По логике работы она напоминает конструктор, поскольку в переменную
days помещается таблица с календарем на текущий месяц текущего года. Тем не менее привычного :: здесь не наблюдается. Это один из статических методов класса date. Статические методы наряду с уже знакомыми конструкторами могут возвращать объекты, поэтому в данном случае необходимо присвоить созданный объект переменной. Про статические переменные и методы уже было немного сказано в конце предыдущего урока. Своим появлением они обязаны тому факту, что некоторые объекты или их свойства (поля) существуют в единственном экземпляре, как, например, календарь на заданный месяц или URI страницы. Поэтому подобные объекты и поля выделены в отдельную группу и к ним можно обращаться напрямую, без использования конструкторов. В случае если мы обращаемся к статическому полю, мы получаем значение поля самого класса. В качестве примера можно привести класс math, предназначенный для работы с математическими функциями. Поскольку существует только одно число p, то для того, чтобы получить его значение, используется статическое поле $math:PI - это значение поля самого класса math.

В результате исполнения этого кода в переменной
days будет содержаться такая таблица.

Таб. 1 (для июня 2023 года)

0

1

2

3

4

5

6

 



01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30





Это таблица, содержащая порядковые номера дней недели и календарь на июнь 2023 г.

С ней мы и  будем дальше работать. Нельзя сразу же выводить содержимое переменной
$days, просто обратившись к ней по имени. Если мы обратимся к таблице просто как к переменной, будет непонятно, что мы хотим получить - строку, всю таблицу целиком или значение только из одного столбца. Также явно требуется доработка содержимого полученной таблицы. Но ведь не зря же мы создавали хеш с названиями дней недели и месяцев! Поэтому далее по коду средствами HTML создается таблица, в первой строке которой мы выводим название текущего месяца, пользуясь данными из хеша, связанными с номером месяца в году:

$calendar_locale.month_names.[$now.month]

Что здесь что? Мы выводим значение поля
month_names хеша calendar_locale с порядковым номером текущего месяца, полученным как $now.month. Результатом выполнения этой конструкции будет название месяца на русском (или любом другом) языке, которое было определено в хеше.

В следующей строке календаря выведем названия дней недели, пользуясь данными хеша. Сформулируем задачу подробнее. Нам надо последовательно перебрать номера дней недели (от 0 до 6) и поставить в соответствие номеру дня его название из поля
day_names хеша calendar_locale. Для этой цели удобнее всего воспользоваться циклом - последовательностью действий, выполняющейся заданное количество раз. В данном случае мы используем цикл for. Его синтаксис такой:

^for[счетчик](диапазон значений, например 0;6){последовательность действий}

Одно из достоинств циклов - возможность использования значения счетчика внутри цикла при обращении к нему как к переменной. Этим мы и воспользуемся:

^for[i](0;6){
   <th class="weekday week${i}day">
      $calendar_locale.day_names.$i
   </th>
}

Все просто и понятно, если знать, что такое цикл: последовательно меняя значение
i от 0 до 6 (здесь i является счетчиком цикла), мы получаем семь значений:

week${i}day - для названия стиля дня недели; если написать week$iday, Parser поймет это как обращение к переменной $iday; фигурными скобками возможно отделить имя переменной от следующих за ним букв;
$calendar_locale.day_names.$i - Для названия дня недели.

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

В этом месте может возникнуть вопрос: «Зачем мы задаем стиль дням недели?» Ответ прост: «Все должно быть красиво!» Если есть возможность максимально приблизить наш календарь к реальному, то так и сделаем - перекрасим выходные дни в красный цвет.

Далее по тексту следует большой красивый блок. Чтобы в нем разобраться, определимся с задачами. Итак, нам нужно:
1)последовательно перебрать строки таблицы days (таб. 1);  
2)в каждой строке таблицы days последовательно перебрать и вывести значения столбцов (числа месяца);  
3)корректно вывести пустые столбцы (то есть проверить первую и последнюю недели месяца на полноту);  
4)как-то выделить текущее число, например другим цветом и жирным шрифтом.  
   
Приступаем. Первый пункт решается с помощью знакомого метода
menu класса table:

^days.menu{…}

Перебор столбцов логичнее всего реализовать при помощи цикла
for, с которым мы только что познакомились:

^for[i](0;6){…}

Для проверки столбцов на пустоту для вывода столбцов без чисел используем оператор
if.

^if($days.$i){
   …
}{
   
<td></td>
}

При этом в условии
if мы ни с чем не сравниваем значение $days.$i. Так осуществляется проверка на неравенство нулю.

Parser 3 это условие понимает так:

«Если значение
$days.$i больше нуля, то выполняется код {…}, если нет, то выводится пустая ячейка таблицы серого цвета».

Основная часть работы выполнена. Осталось только выделить текущее число. Решается это использованием еще одного
if, где в качестве условия задается сравнение текущего значения таблицы days с текущим числом ($days.$i==$now.day):

<td class="^if($days.$i == $now.day){today}">
   $days.$i
</td>

Здесь мы проверяем на равенство два числа, поэтому задействуем оператор
== вместо eq, используемый для проверки равенства строк.

Еще раз посмотрим на общую структуру формирования календаря:

#перебираем строки таблицы с календарем
^days.
menu{

#перебираем столбцы таблицы с календарем   
   ^
for[i](0;6){
      ^if($days.week_day){
         ^if($month.$week_day==$date.day){ 
стиль с жирным шрифтом }
         число
      }{
         пустой столбец
      }
   }
}

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

Тому, кто хочет убедиться в работоспособности данного модуля, достаточно создать в разделе
/news/ файл test.html всего с одной строчкой ^calendar[]. Осталось лишь обратиться к этому файлу из браузера и полюбоваться на результат своих трудов.

Подведем итоги третьего урока.

Что мы сделали: описали функцию, формирующую календарь на текущий месяц.

Что узнали:

·Файл auto.p может содержаться не только в корневом каталоге сайта, но и в любом другом, при этом функции, в нем определенные, явно доступны только внутри этого каталога.  
·Переменная-хеш - это массив, необходимый для построения связи одних объектов с другими; в нашем случае в качестве объектов выступали строки.  
·Статический метод calendar создает таблицу с календарем на текущий месяц.  
·Цикл for позволяет последовательно выполнить определенные действия заданное количество раз.  

Что надо запомнить:

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

Поскольку код становится все объемнее, неплохо бы начать снабжать его комментариями, чтобы потом было легче разбираться. В Parser комментарием считается любая строка, начинающаяся со знака
#. До сих пор мы не пользовались этим, но в дальнейшем нам пригодится комментирование кода. Следующая строка - пример комментария:

# весь этот текст Parser проигнорирует: это комментарий!

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

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


Copyright © 1997–2024 Art. Lebedev Studio | http://www.artlebedev.ru Дата обновления: 16.10.2024