offline version v3
Запись на курсы по HTML, CSS, JavaScript, PHP, фреймворкам и CMS,
а также: помощь в поиске работы и заказов, стажировка на реальных проектах→
⊗ppOpClLnkAL 109 of 179 menu

Активация ссылок в классе 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 класс).