Активация ссылок в классе Link
После выполнения задач у вас должна получится менюшка. Давайте сделаем так, чтобы в этой менюшке выделялась каким-то образом та ссылка, на странице которой мы находимся.
Такая ссылка обычно называется активной
и ее выделение происходит путем добавления
ей 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 класс).