Создание новой темы. Часть вторая: page.tpl.php.

Главные вкладки

Аватар пользователя steel.ne steel.ne 3 апреля 2007 в 14:10

Разберем подробнее HTML-структуру странички. Тема та же - стандартная Bluemarine.

После того, как мы посмотрели исходник готовой страницы, самое время немного полазить по файлам .tpl.php. Исключительно для понимания структуры. Сегодня мы их все еще менять не будем.

Итак, главный, центровой файл page.tpl.php в студию!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="<?php print $language ?>" xml:lang="<?php print $language ?>">

<head>
  <title><?php print $head_title ?></title>
  <?php print $head ?>
  <?php print $styles ?>
  <?php print $scripts ?>
  <script type="text/javascript"><?php /* Needed to avoid Flash of Unstyle Content in IE */ ?> </script>
</head>

Что мы видим тут по сравнению со вчерашними наблюдениями? Как и следовало из расширения - это обычный PHP-файл. Поскольку PHP в душе уже сам шаблон, то почему бы его и не использовать по прямому назначению? Итак, до вызова этого файла в переменных $head, $styles, $scripts и т.д. находятся уже сгенерированные куски нашей страницы. А в этом шаблоне мы их собственно и выводим в том порядке, в котором хочется дизайнеру/верстальщику.

<body>
<table border="0" cellpadding="0" cellspacing="0" id="header">

Главное в этом фрагменте - начинается таблица с id #header. В файлах *.css часть ее свойств будут наследованы от вышестоящих элементов (в нашем случае body), часть будет описана для всех таблиц в целом, а некоторые свойства - непостредственно для данной таблицы. То есть если мы хотим что-то изменить в отображении верхней полоски - нам надо рыть внутри свойств этой таблицы.

<tr>
    <td id="logo">
      <?php if ($logo) { ?><a href="<?php print $base_path ?>" title="<?php print t('Home') ?>"><img src="<?php print $logo ?>" alt="<?php print t('Home') ?>" /></a><?php } ?>
      <?php if ($site_name) { ?><h1 class='site-name'><a href="<?php print $base_path ?>" title="<?php print t('Home') ?>"><?php print $site_name ?></a></h1><?php } ?>
      <?php if ($site_slogan) { ?><div class='site-slogan'><?php print $site_slogan ?></div><?php } ?>
    </td>

Ячейка с id #logo. Уже наверное понятно, что если нам что-то надо от этой ячейки - добро пожаловать в секцию #logo { ... } файла .css.
Обращаем внимание, что картинка-логотип не имеет своего отдельного id и даже класса. С одной стороны, если сильно прижмет, можно и поправить этот файл (но не рекомендуется делать до начала соответствующего урока!), либо обращаться к этой картинке как #logo img { } (то есть ко всем картинкам элемента #logo, что в данном случае прокатит, поскольку в нем всего одна картинка). Зачем нам переопределять свойства картинки? Ну вдруг захотим размер поменять, или рамочкой обвести. Дизайнеры - они такие непредсказуемые.

Для тех, кто не умеет в уме вычищать теги <?php  ?>, смотрим во что в результате превращается этот кусок шаблона:

<td id="logo">
        <a title="Home" href="/">
                <img alt="Home" src="/themes/bluemarine/logo.png"/>
        </a>
        <h1 class="site-name">
                <a title="Home" href="/">Drupal</a>
        </h1>
</td>

Отступы и переводы строк сделаны мной для удобства чтения. На самом деле не совсем мной, а очень полезным Firebug'ом. Так что если еще не поставили его себе - срочно исправить упущение.

Маленькое отступление, чтобы не запутывать пытливых читателей: это плагин при разборе страницы самопроизвольно меняет местами свойства внутри тэгов. Например, если просмотреть исходник страницы, то тег <img> на самом деле выглядит так: <img src="/themes/bluemarine/logo.png" alt="Home" />. То есть как и в шаблоне, сначала идет свойство src, и только потом alt. Просьба не пугаться, шаблон выводится строго посимвольно.

    <td id="menu">
      <?php if (isset($secondary_links)) { ?><?php print theme('links', $secondary_links, array('class' =>'links', 'id' => 'subnavlist')) ?><?php } ?>
      <?php if (isset($primary_links)) { ?><?php print theme('links', $primary_links, array('class' =>'links', 'id' => 'navlist')) ?><?php } ?>
      <?php print $search_box ?>
    </td>
  </tr>
  <tr>
    <td colspan="2"><div><?php print $header ?></div></td>
  </tr>
</table>

В этой ячейке с id #menu выводятся первичные и вторичные ссылки (если определены конечно). Вот эта конструкция <?php if (isset($primary_links)) { ?> отвечает за вывод частей шаблона. И поэтому, если $primary_links не определены, то ничего туда и выводиться не будет. Если обратили на это внимание еще в прошлом фрагменте, то не вывелся целиком <div class='site-slogan'> со слоганом сайта. Для чего такие сложности? Просто без использования такой конструкции если не будет слогана, то останутся его уши в виде открывающего и закрывающего тега

. А это может изрядно попортить дизайн.
<table border="0" cellpadding="0" cellspacing="0" id="content">
  <tr>

Тут начинается самое интересное - таблица контента. С понятным id.

    <?php if ($sidebar_left) { ?><td id="sidebar-left">
      <?php print $sidebar_left ?>
    </td><?php } ?>

Сайдбар - это столбики слева и справа от основного тела сайта. Туда выводятся разные блоки. Например меню, блок входа и т.д. Собственно ширину это колонки можно легко задать в свойствах #sidebar-left. Ну и как уже догадались, если у нас никаких блоков ни слева ни справа нет, то вся ячейка просто не выводится.

    <td valign="top">
      <?php if ($mission) { ?><div id="mission"><?php print $mission ?></div><?php } ?>
      <div id="main">
        <?php print $breadcrumb ?>
        <h1 class="title"><?php print $title ?></h1>
        <div class="tabs"><?php print $tabs ?></div>
        <?php print $help ?>
        <?php print $messages ?>
        <?php print $content; ?>
        <?php print $feed_icons; ?>
      </div>
    </td>

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

<?php if ($sidebar_right) { ?><td id="sidebar-right">
      <?php print $sidebar_right ?>
    </td><?php } ?>
  </tr>
</table>

<div id="footer">
  <?php print $footer_message ?>
</div>
<?php print $closure ?>
</body>
</html>

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

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

Комментарии

Аватар пользователя Dan Dan 4 апреля 2007 в 0:11

Что меня бесит, так это строки типа:

<?php if ($logo) { ?>
<a href="<?php print $base_path ?>" title="<?php print t('Home') ?>"><img src="<?php print $logo ?>" alt="<?php print t('Home') ?>" /></a><?php } ?>
<?php if ($site_name) { ?>
<h1 class='site-name'><a href="<?php print $base_path ?>" title="<?php print t('Home') ?>"><?php print $site_name ?></a></h1><?php } ?>
<?php if ($site_slogan) { ?>
<div class='site-slogan'><?php print $site_slogan ?></div><?php } ?>

Предпочитаю более читабельные конструкции:
$home = t('Home');
if($logo)
print ('$home');

if ($site_name)
print('$site_name');

if ($site_slogan)
print('

$site_slogan

');
?>

Если HTML-кода много, можно использовать php-оператор <<<.
Почти всех просто прёт сто раз писать

PS: Сорри за оффтоп, просто накипело.

Аватар пользователя steel.ne steel.ne 4 апреля 2007 в 0:20

Эти замысловатые конструкции лучше обрабатываются каким-нибудь визуальным HTML-редактором.
А твой подход мне напоминает Perl Wink

Аватар пользователя Dan Dan 4 апреля 2007 в 0:54

Я пользуюсь редакторами с подсветкой кода. В понимании проблем нет - просто не люблю лишние буквы.

-- А твой подход мне напоминает Perl Wink
Я сишник Smile

Аватар пользователя romandor romandor 4 апреля 2007 в 9:17

теоретически, первый вариант работает быстрее поскольку строки не обрабатывется интерпретатором php, в твоём примере - дополнительные функции print.

Аватар пользователя Dan Dan 4 апреля 2007 в 11:00

Чего-то я не понимаю, видимо...

При условии срабатывания всех if-ов, в первом примере восемь раз вызывается ф-я print, и два раза - t(), в моём - три раза print и один раз t() (кстати, а ф-я t() в данном случае лезет в базу за переводом или нет?).

Но я думаю это "ловля блох" и на эффективности не сильно сказывается (сам знаешь, где у Drupal слабые места), а вот понятности добавляет.

Аватар пользователя 4matic 4matic 5 апреля 2007 в 2:56

Не понял, почему интерпритатор вызывается 10 раз.
Что касается кавычек. Я за то, что бы выносить чистый HTML за пределы <?php ?>. Потому что:

  1. PHP парсит только то, что в пределах тега <?php?>
  2. нет заборов из обратных слешей для экранирования капризных символов
  3. Работа с чистым HTML достаточно удобна. Все отлично копируется и вставляется из шаблонов в код и обратно
Аватар пользователя Dan Dan 5 апреля 2007 в 10:54

> Не понял, почему интерпритатор вызывается 10 раз.
Я так понимаю работу апача (поправьте если не прав) при разборе файла он встречает конструкцию <?php ?>, для её обработки сразу, на месте, вызывается связанный обработчик (в данном случае - PHP). Если эта конструкция встречается 10 раз - обработчик вызывается 10 раз. Я правильно понимаю механизм? Кто знает точно?

Аватар пользователя SadhooKlay SadhooKlay (не проверено) 5 апреля 2007 в 15:22

Так, но не совсем.
Обработчик php вызывается сразу, в месте с сервером.
В простейшем примере, запускается Apache, он запускает своего потомка, а потомок запускает обработчик.
И все это ещё до того, как ты открыл сайт на localhost.

Аватар пользователя Dan Dan 5 апреля 2007 в 16:24

Про потомка понятно. Вопрос, как именно запускаются обработчики. Ты говоришь, что одновременно с апачем, но мне кажется это только в случае, если обработчик встроен как модуль, а если как CGI (или FastCGI)?

Аватар пользователя SadhooKlay SadhooKlay (не проверено) 5 апреля 2007 в 18:46

Точно не скажу, по моему в FastCGI принцип тот, который ты описал выше.

Аватар пользователя NurOff NurOff 6 февраля 2008 в 12:37

От темы отошли ребята. А тема очень интересная.
Насчет php. При запуске апач загружаются все подключенные библиотеки.
В случае моего последнего вебсервера эта библиотека php5apache2_2.dll.
Так что мне кажется правильно когда мы не заставляем сервер обрабатывать html через php то есть метод print, echo или content ^_^

Аватар пользователя KalanSPb KalanSPb 25 марта 2008 в 7:39

Quote:
при разборе файла он встречает конструкцию , для её обработки сразу, на месте, вызывается связанный обработчик (в данном случае - PHP). Если эта конструкция встречается 10 раз - обработчик вызывается 10 раз. Я правильно понимаю механизм? Кто знает точно?

Как бы не вызывался (модуль, CGI, FastCGI) интерпретатор PHP, Apache как только понимает, что файл php (грубо говоря, видит расширение .php), сразу отдает его интерпретатору, а сам ничего не парсит, а уже интерпретатор переключается в режимы простой выдачи и выполнения команд (причем первый работает быстрее естественно). Сам Apache про теги <?php ?>, <? ?>, <?= ?> и т. п. ничего не знает (как, в принципе, ничего не знает и про html теги). Его задача (упрощенно) понять, каким обработчиком нужно обработать запрос браузера, что и как этому обработчику задать в качестве параметров (какой файла он будет обрабатывать главное) и как выдать браузеру результаты работы обработчика (в случае php, например, определить какие HTTP заголовки выдал интепретатор сам и их уже не выводить). Вообще Apache - это HTTP сервер, все что касается HTML, PHP, Perl, C и т. д. его не волнует, максимум HTTP заголовки анализирует и свои добавляет

Quote:
Почти всех просто прёт сто раз писать <?php ?>

Совет: настроить горячие клавиши (или внутренние шаблоны редактора), например <?php print ?> на ctrl+shift+p повесить

Сам спор "PHP внутри HTML" или наоборот вечен, как вечен PHP Smile Есть и плюсы, и минусы у обоих подходов (а есть еще и другие подходы). Первого обычно придерживаются те, кто привык работать в команде с разными дизайнерами/верстальщиками/визуальными HTML редакторами :), им достаточно объяснить (поначалу Smile ), что все что внутри "скобок" <?php ?> будет заменено на обычный текст, без всяких тегов и они спокойно могут верстать и править шаблоны. Второго те, кто пришел из мира "серьезного" программирования и делает сайты "под ключ" (максимум дизайнер дает дизайн в .psd). Если кто только начинает осваивать PHP лучше придерживаться первого способа, он универсальнее

З.Ы. Надеюсь кому-то поможет прояснить ситуацию Smile

Аватар пользователя Stargazer Stargazer 15 января 2010 в 13:18

KalanSPb wrote:
Quote:
при разборе файла он встречает конструкцию , для её обработки сразу, на месте, вызывается связанный обработчик (в данном случае - PHP). Если эта конструкция встречается 10 раз - обработчик вызывается 10 раз. Я правильно понимаю механизм? Кто знает точно?

Как бы не вызывался (модуль, CGI, FastCGI) интерпретатор PHP, Apache как только понимает, что файл php (грубо говоря, видит расширение .php), сразу отдает его интерпретатору, а сам ничего не парсит, а уже интерпретатор переключается в режимы простой выдачи и выполнения команд (причем первый работает быстрее естественно). Сам Apache про теги <?php ?>, <? ?>, <?= ?> и т. п. ничего не знает (как, в принципе, ничего не знает и про html теги). Его задача (упрощенно) понять, каким обработчиком нужно обработать запрос браузера, что и как этому обработчику задать в качестве параметров (какой файла он будет обрабатывать главное) и как выдать браузеру результаты работы обработчика (в случае php, например, определить какие HTTP заголовки выдал интепретатор сам и их уже не выводить). Вообще Apache - это HTTP сервер, все что касается HTML, PHP, Perl, C и т. д. его не волнует, максимум HTTP заголовки анализирует и свои добавляет

Quote:
Почти всех просто прёт сто раз писать <?php ?>

Совет: настроить горячие клавиши (или внутренние шаблоны редактора), например <?php print ?> на ctrl+shift+p повесить

Сам спор "PHP внутри HTML" или наоборот вечен, как вечен PHP Smile Есть и плюсы, и минусы у обоих подходов (а есть еще и другие подходы). Первого обычно придерживаются те, кто привык работать в команде с разными дизайнерами/верстальщиками/визуальными HTML редакторами :), им достаточно объяснить (поначалу Smile ), что все что внутри "скобок" <?php ?> будет заменено на обычный текст, без всяких тегов и они спокойно могут верстать и править шаблоны. Второго те, кто пришел из мира "серьезного" программирования и делает сайты "под ключ" (максимум дизайнер дает дизайн в .psd). Если кто только начинает осваивать PHP лучше придерживаться первого способа, он универсальнее

З.Ы. Надеюсь кому-то поможет прояснить ситуацию :)

Полезно, спс!

Аватар пользователя MCProx MCProx 14 ноября 2008 в 11:12

Я тоже сишник помоему удобнее
и читабельней будет как говорит "Dan"
подумайте сами, а если ваш код возмёт ктото из новичков, или начальник захочет поумничать!!
Есть такое понимание как красивый стиль программирования!

Аватар пользователя suna suna 24 сентября 2012 в 23:01

Ребят, подскажите пожалуйста...начал устанавливать новую тему professional_theme... и после установки на экране вся информация пропала...написана ошибка следующая
Fatal error: Call to undefined function i18n_menu_translated_tree() in /home/b/blabla/blabla.ru/public_html/sites/all/themes/themes/professional_theme/templates/page.tpl.php on line 79

подскажите пожалуйста что делать? как вернуть старую тему и всю информацию?

Аватар пользователя NurOff NurOff 24 сентября 2012 в 23:38

"suna" wrote:
подскажите пожалуйста что делать? как вернуть старую тему и всю информацию?

sites\default\settings.php
# $conf['theme_default'] = 'garland';
Уберите камент. Дальше догадаетесь.