Наследование блоков
Наверное, вы думаете, что страница /phil/index.html, которая генерируется листингом30.11, состоит только из трех блоков — Title, Text и Cite. Это не так. Страница, без сомнения, включает перечисленные блоки, но она также состоит и из всех блоков, которые заданы для каталогов /phil и /. Каталоги ведь ничем не хуже файлов. Соответственно, каждый каталог также может иметь собственный набор блоков, которые будут унаследованы
всеми файлами в нем, а также файлами его подкаталогов.
Предположим, что для каталога /phil определяется блок Title, содержащий, скажем, строку Weekly. В то же время файл index.html
также определяет блок Title. Что произойдет в этом случае? А произойдет следующее: в шаблоне будет доступно только тело последнего блока. Иными словами, тот блок, который определяется в файле, заменит собой
свое старое значение из каталога.
Нетрудно теперь догадаться, как происходит процесс сбора блоков для конкретной запрошенной страницы. Вначале шаблонизатор получает все блоки корневого каталога, затем обрабатывает блоки подкаталога, причем уже имеющиеся одноименные блоки перезаписываются. Описанный процесс продолжается до тех пор, пока не будет достигнут файл, который запрошен пользователем. Такая организация шаблонизатора позволяет нам задавать для всех блоков значения по умолчанию. Эти значения будут использованы шаблоном в случае, если те или иные блоки не "переопределяются" в файле страницы. Чтобы задать тело по умолчанию для блока, достаточно добавить его к блокам корневого каталога сайта.
Мы знаем, что блоки файла хранятся в самом этом файле. Где же находятся блоки каталога? Конечно, в специальном файле, расположенном в этом каталоге.
Хранить блоки каталогов в отдельном централизованном хранилище (наподобие Реестра Windows) было бы большим просчетом. Этим мы перечеркнули бы принцип минимизации зависимостей данных, о котором так много сказано в этой главе.
Я предлагаю использовать в качестве такого файла .htaccess. Чтобы Apache не "ругался" на не непонятные ему директивы <?Block(...)?>, мы снабдим их символами комментария # в начале строки. Конечно, таким способом мы не сможем задавать многострочные блоки для каталогов, но, как показывает практика, в большинстве случаев это и не нужно. В листинге 30.12 показан пример файла .htaccess, расположенного в корневом каталоге сервера и задающего значения блоков по умолчанию.
Листинг 30.12. Блоки для корневого каталога: /.htaccess
#<?Inc("templ")?>
#<?Block("DefaultGlue"," | ")?>
#<?Block("Template","default.tmpl")?>
#<?Block("Title","Тестовый сервер")?>
# Связываем имя обработчика с конкретным файлом.
Action templhandler "/php/TemplateHandler.php?"
# Документы этого типа мы желаем "пропускать" через наш обработчик.
AddHandler templhandler .html .htm
Обратите внимание на то, что в приведенном файле конфигурации задаются также и некоторые директивы Apache, которые заставляют сервер запускать программу шаблонизатора каждый раз, когда пользователь обращается к HTML-документу. Мы уже знакомы с этими директивами: в главе 29
они использовались для того, чтобы обеспечить подключение библиотекаря к каждому сценарию сервера.
Наверное, вы уже заметили, что блочный файл, который обрабатывается шаблонизатором, представляет собой ни что иное, как код на PHP с вызовами управляющих функций типа Block(). Этим мы достигаем множества преимуществ, самое главное из которых — значительное ускорение работы шаблонизатора по сравнению со способом "ручного" разбора файлов. Кроме того, отладочные качества сценария при таком подходе ничего не теряют: файлы блоков загружаются с помощью include, а значит, случись там ошибка, PHP исправно покажет имя файла и номер строки, где это произошло. Правда, остается единственный недостаток: несколько некрасивый синтаксис определения блоков, естественный лишь для программиста, но не для дизайнера. Что же, всегда приходится идти на какие-то жертвы…
Внимательно взгляните на определение блока Template. Как уже упоминалось, этот блок содержит имя шаблона, который будет задействоваться при отображении страницы. То, что блоки из родительских каталогов наследуются файлами, позволяет нам задать Template в одном-единственном месте, автоматически распространив его действие на все файлы в каталоге. Не правда ли, это как раз то, чего мы так долго добивались?
Шаблонизатор также обрабатывает специальным образом еще один блок. Его название — Output. Тело именно этого блока выводится в браузер пользователя, когда вся страница уже обработана. Обычно блок Output
вставляют только в шаблон страницы, потому что использование его в любом другом месте оказывается бессмысленным (все равно он переопределится в шаблоне).