Разработка «Хвостикам дом»
Предыстория
Описание этапов работы
После того как я получил готовый дизайн будущего сайта, я должен был определиться с подключаемыми плагинами. Если структура предполагает наличие каталога, фильтр и поиск по товарам, то логичным решением выглядит подключение WooCommerce.
И кошки, и собаки будут фильтроваться по состоянию здоровья, наличию опекуна, полу, цвету, типу шерсти и возрасту. С фильтрацией отлично справляется плагин WOOF — WooCommerce Products Filter.
Заказчик хотел, чтобы атрибуты по состоянию здоровья склонялись в зависимости от пола питомца. Для этого я написал проверку:
<?php $state = $product->get_attribute('pa_state'); ?>
<?php $sex = $product->get_attribute('pa_sex'); ?>
<?php if ($state == 'Здоров' && $sex == 'Мальчик') { ?>
<div class="pet-main__gallery-state pet-main__gallery-state--healthy">Здоров</div>
<?php } else if ($state == 'Здоров' && $sex == 'Девочка') { ?>
<div class="pet-main__gallery-state pet-main__gallery-state--healthy">Здорова</div>
<?php } else if ($state == 'Инвалид') { ?>
<div class="pet-main__gallery-state pet-main__gallery-state--disabled">Инвалид</div>
<?php } else if ($state == 'На лечении') { ?>
<div class="pet-main__gallery-state pet-main__gallery-state--on-treatment">На лечении</div>
<?php } ?>
А для того, чтобы у клички питомца появился гендерный символ, пришлось прописать условие в файл WooCommerce title.php:
$sex = $product->get_attribute('pa_sex');
if ($sex == 'Девочка') {
the_title( '<h1 class="product_title entry-title pet-main__sex pet-main__sex--girl">', '</h1>' );
} else if ($sex == 'Мальчик') {
the_title( '<h1 class="product_title entry-title pet-main__sex pet-main__sex--boy">', '</h1>' );
}
Самой интересной задачей было написание небольшого скрипта для автоматического определения возраста питомца. Идея была такой – администратор сайта должен указать день рождения животного, а алгоритм должен вывести на сайт его возраст на текущий день в формате: «5 лет», а если питомцу меньше года, то результат в месяцах. Причем следует учитывать склонение слова, которое стоит после числа. У меня вышел такой скрипт:
function age() {
const birthday = document.querySelectorAll(".product-content__birthday");
birthday.forEach((e) => {
if (e.innerHTML.length == 0) {
return false;
} else {
const text = e.innerHTML;
const birthdayYear = text.replace(/\d+\/\d+\/(\d+)/g, "$1");
const birthdayMonth = text.replace(/\d+\/(\d+)\/\d+/g, "$1");
const birthdayDay = text.replace(/(\d+)\/\d+\/\d+/g, "$1");
let newFormatBirthday = new Date(
birthdayYear,
birthdayMonth - 1,
birthdayDay
);
let nextSibling = e.nextElementSibling;
nextSibling.innerHTML = getAge(newFormatBirthday);
}
});
function getAge(dateString) {
let today = new Date();
let birthDate = new Date(dateString);
let age = today.getFullYear() - birthDate.getFullYear();
let m = today.getMonth() - birthDate.getMonth();
let d = today.getDate() - birthDate.getDate();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
if (m < 0) {
m = 12 + m;
if (d < 0 || (d === 0 && today.getDate() < birthDate.getDate())) {
m--;
}
} else {
m = 0;
}
let ageWord;
let mWord;
if (age === 1) {
ageWord = " год";
} else if (age > 1 && age < 5) {
ageWord = " года";
} else if (age > 4) {
ageWord = " лет";
}
if (age < 1 && m === 1) {
mWord = " месяц";
} else if (age < 1 && m > 1 && m < 5) {
mWord = " месяца";
} else if (age < 1 && m > 4) {
mWord = " месяцев";
} else if (age < 1 && m < 1) {
m = "";
mWord = "меньше месяца";
}
return age ? age + ageWord : m + mWord;
}
}
Изначально блок справа в дизайне выглядел статичным.
Я предложил дизайнерам ввести небольшую анимацию, они согласились. Вот, что из этого вышло.
Я добился этого с помощью стилей:
.front-stages-list__item::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 58px;
height: 58px;
}
.front-stages-list__item:nth-child(1):before {
animation: sequence-1 5s infinite ease-in-out;
}
.front-stages-list__item:nth-child(2):before {
animation: sequence-2 5s infinite ease-in-out;
}
.front-stages-list__item:nth-child(3):before {
animation: sequence-3 5s infinite ease-in-out;
}
.front-stages-list__item:nth-child(4):before {
animation: sequence-4 5s infinite ease-in-out;
}
@keyframes sequence-1 {
0% {background: url('img/stages/front-stage-1.svg') center/cover no-repeat;}
20% {background: url('img/stages/front-stage-1--hover.svg') center/cover no-repeat;}
100% {background: url('img/stages/front-stage-1.svg') center/cover no-repeat;}
}
@keyframes sequence-2 {
0% {background: url('img/stages/front-stage-2.svg') center/cover no-repeat;}
40% {background: url('img/stages/front-stage-2--hover.svg') center/cover no-repeat;}
100% {background: url('img/stages/front-stage-2.svg') center/cover no-repeat;}
}
@keyframes sequence-3 {
0% {background: url('img/stages/front-stage-3.svg') center/cover no-repeat;}
60% {background: url('img/stages/front-stage-3--hover.svg') center/cover no-repeat;}
100% {background: url('img/stages/front-stage-3.svg') center/cover no-repeat;}
}
@keyframes sequence-4 {
0% {background: url('img/stages/front-stage-4.svg') center/cover no-repeat;}
80% {background: url('img/stages/front-stage-4--hover.svg') center/cover no-repeat;}
100% {background: url('img/stages/front-stage-4.svg') center/cover no-repeat;}
}
После того как сайт был готов, заказчик принялся тестировать его. Правок было мало и все они были незначительные, поэтому вскоре сайт был перенесен на основной домен.