Класс Link
Давайте сделаем класс, который будет создавать
HTML ссылку. Назовем его Link
. Вот
так мы будем пользоваться нашим классом:
<?php
// Выведет <a href="/test.html">link</a>:
echo (new Link())->setAttr('href', '/test.html')->setText('link')->show();
?>
Реализация:
<?php
class Link extends Tag
{
public function __construct()
{
parent::__construct('a');
}
}
?>
Сделаем так, чтобы даже если атрибут href
не задан, то по умолчанию он становился пустыми
кавычками:
<?php
class Link extends Tag
{
public function __construct()
{
parent::__construct('a');
$this->setAttr('href', '');
}
}
?>
Проверим:
<?php
// Выведет <a href="">index</a>:
echo (new Link())->setText('index')->show();
?>
Самостоятельно реализуйте описанный класс
Link
.
С помощью этого класса создайте меню из 5
ссылок. Пусть первая ссылка ведет на страницу
/1.php
, вторая - на страницу /2.php
и так далее.
Разместите созданную менюшку в отдельном
файле, например, в menu.php
.
Создайте страницы, на которые ведут ссылки вашей менюшки. Добавьте в ним какой-нибудь текст.
Подключите инклудом к тексту каждой страницы вашу менюшку из файла. Убедитесь, что ссылки из этой менюшки будут работать корректно.
Активация ссылок
После выполнения задач у вас должна получится менюшка. Давайте сделаем так, чтобы в этой менюшке выделялась каким-то образом та ссылка, на странице которой мы находимся.
Такая ссылка обычно называется активной
и ее выделение происходит путем добавления
ей CSS класса active
(общепринятое
название).
Добавленный к ссылке класс active
каким-то образом выделяет ее - подчеркивает,
красит в красный цвет и тому подобное: все
это регулируется CSS стилями для этого класса.
Итак, давайте сделаем так, чтобы ссылки автоматически
активировались (добавляли себе CSS класс
active
), если их href
совпадает
с урлом сайта.
URL
сайта можно достать вот так:
<?php
echo $_SERVER['REQUEST_URI'];
?>
Чтобы прочитать href
нашей ссылки,
используем геттер getAttr
, унаследованный
от родительского класса Tag
. Вот так:
<?php
$href = $this->getAttr('href');
?>
Чтобы добавить нашей ссылке CSS класс active
,
используем метод addClass
, также унаследованный
от родителя. Вот так:
<?php
$this->addClass('active')
?>
Соберем все вместе и напишем вспомогательный
метод activateSelf
, который будет
проверять, совпадает ли href
ссылки
и URI
, и активировать ее, если это так:
<?php
private function activateSelf()
{
if ($this->getAttr('href') === $_SERVER['REQUEST_URI']) {
$this->addClass('active');
}
}
?>
Осталось придумать в каком месте вызывать
созданный нами метод. В конструкторе класса
Link
этого делать нельзя, так как
в момент вызова конструктора href
ссылки еще не задан (конструктор же вызывается
в самом начале, а потом методы цепочки, в
том числе setAttr
, который и задает
href
ссылки).
После таких рассуждений становится очевидным,
что метод activateSelf
следует вызвать
в момент вывода ссылки на экран, то есть
в методе show
, с помощью которого
скорее всего и будет формироваться ссылка.
Однако, представляется возможным то, что
при использовании нашего класса кто-то будет
применять метод open
и метод close
отдельно.
Хотя описанное выше и маловероятно, тем не
менее вызовем метод activateSelf
в
методе open
, переопределив тем самым
метод родителя:
<?php
class Link extends Tag
{
public function __construct()
{
$this->setAttr('href', '');
parent::__construct('a');
}
// Переопределяем метод родителя:
public function open()
{
$this->activateSelf(); // вызываем активацию
return parent::open(); // вызываем метод родителя
}
private function activateSelf()
{
if ($this->getAttr('href') === $_SERVER['REQUEST_URI']) {
$this->addClass('active');
}
}
}
?>
Так как метод show
использует внутри
себя метод open
, то изменения для
метода show
произойдут автоматически.
Можем теперь проверить работу нашего класса:
<?php
echo (new Link)->setAttr('href', '/index.php')->setText('index')->show();
/*
Если URL страницы не /index.php,
то результат выполнения кода выведет
<a href="/index.php">index</a>
Если URL страницы /index.php,
то результат выполнения кода выведет
<a href="/index.php" class="active">index</a>
*/
?>
Итак, теперь ссылки активируют сами себя.
Это реально круто! При этом нам понадобилось
совсем мало кода, чтобы реализовать такое
поведение. Все потому, что у нас есть базовый
класс Tag
, который прячет внутри себя
много универсального кода для манипуляций
с тегами.
Реализуя новые классы на основе класса Tag
мы не держим в голове детали реализации этого
класса Tag
. И вообще не видим код
этого класса - он где-то в другом файле (если,
конечно же, вы его туда вынесли) и не мешает
нам работать. Мы просто знаем, какие методы
предоставляет этот класс своим потомкам -
и пользуемся ими.
Поэтому классы-потомки и получаются такими маленькими и изящными.
На самом деле наш код класса Link
еще более крут, чем кажется. Дело в том,
что наши ссылки могут иметь и другие - постоянные
- классы. При этом наша активация никак не
будет мешать этим классам - они будут оставаться,
просто к ним будет добавляться еще и класс
active
.
Все потому, что так работает метод addClass
- он добавляет новый класс к уже существующим
классам.
Вот пример:
<?php
echo (new Link)
->setAttr('href', '/index.php')
->setAttr('class', 'link1 link2') // добавляем ссылке классы
->setText('index')
->show();
/*
Результат выполнения кода выведет
<a href="/index.html" class="link1 link2 active">index</a>
*/
?>
Добавьте в ваш класс Link
активацию ссылок.
Проверьте работу активации ссылок на менюшке, которую вы создали в предыдущих задачах. Характерно, что правки в саму менюшку вносить не надо - создание ссылок никак не поменялось, просто ссылки теперь активируют сами себя. Попереходите по ссылкам меню и убедитесь в том, что соответствующие ссылки активируются.
Не очень хорошо то, что название класса active
жестко зашито в коде (вдруг мы захотим поменять
его на другое). Вынесите его в константу
класса (константу используем для того, чтобы
в процессе работы скрипта случайно не изменить
наш CSS класс).