Как внести правки на сайт «под Битриксом» и не сломать свою психику. Часть 1.

Действующие лица:
1.Отдельно живущий калькулятор стоимости услуг. Со своей маленькой админкой, для управления курсами/коэффициентами, простейшим АПИ, для создания на его основе всевозможных прайс-листов.

  • База — MySQL
  • Бэк — PHP
  • Фронт — классика HTML+CSS+JS

2. Корпоративный сайт на «1С-Битрикс: Управление сайтом 15.5.10». Лицензия сдохла и оплачиваться не собирается. Крайнее обновление: 09.11.2016 22:01:05 (8 месяцев назад. Ну, могло быть и хуже).
3. Горе-программист (Я), никогда не имевший доселе дела с Битриксом.

Задача:
Внедрить калькулятор на сайт. На основе установленных в нем цен — выводить прайс-листы на страницах-описаниях соответствующих товаров.

Открыв Битрикс-админку, я сперва маленько опешил. Столько кнопок-свестелок-звонилок я еще нигде не видел. Но это не беда. Продукт-то (надеюсь) человеко-ориентированный. Не обосрусь Справлюсь!

Первое, что конкретно дезориентирует в админке — дизайн. Решил я глянуть на компоненты, что они собой представляют, и как с ними общаться не залезая в код. Смотрю — формы есть какие-то. Дай, думаю, гляну, как настроено. А там… Вот как это по-вашему называется?

Вот я был больше чем уверен, что попаду в настройки формы. Но не в сообщения, которые через эту форму приходят от клиентов. Здесь необходимо выделить 2 момента:

  1. Увиденное мной, с первого взгляда даже не похоже на то чем является. Если здесь собираются месаджи от клиентов — то где привычные всему миру индикаторы? Как, черт возьми, мне понять, зайдя с утра в админку, что у меня есть новые непрочитанные месаджи? Какого черта они собираются здесь, внутри движка, а не уходят на почты манагеров? (С этим разберемся, может быть где-то галочка не стоит нужная, заветная).
  2. Это вобще не похоже на месадж. Это — форма для заполнения. Вот это всё как оно выглядит сейчас — призывает своим видом к её немедленному заполнению, а не к чтению. Ок. Главное что я понял что это. Не сразу-сходу, но понял.

Дабы избежать дальнейших удивительных открытий, я пошел курить мануалы. Процитирую краеугольные заповеди Битрикс-разрабов:

  • Если вы сопровождаете живой сайт и заказчик просит провести работы по доделке-расширению функционала, то сначала проверьте, а пользуются ли вообще этим функционалом. Проверить можно так:

    Если блок мёртвый, то лучше его вообще убрать или переформулировать ТЗ.

  • Если вы хотите внести какие-то изменения в работе сайта, то:
    • Сначала формализуйте свои требования на листе бумаги, а не кидайтесь править код.
    • После этого заново просмотрите все случаи использования на сайте модифицируемого вами блока. Убедитесь, что всё логично. Очень часто делают небольшие, казалось бы, изменения, а потом оказывается, что страдает связанный функционал, о котором не подумали или забыли.
    • После того, как вы формализовали потребности в изменениях, посмотрите, какие сущности эти требования затрагивают.
    • Только после этого подумайте, какие средства использовать для достижения своих целей.
  • Способы внесения изменений и желательный порядок их применения:
    • сначала попытайтесь сделать это редактированием шаблона самого сайта и файлов CSS;
    • если предыдущее невозможно, то попытайтесь сделать это средствами редактирования страницы сайта;
    • при невозможности реализации задачи с помощью первых вариантов переходите к редактированию шаблонов компонента и файлов CSS компонента, либо изменяйте вывод данных с помощью файлов result_modifier.php и component_epilog.php.
    • используйте обработчики событий, которые позволяют решать очень широкий спектр задач.
    • кастомизация компонента или разработка собственного компонента или модуля — последний из возможных вариантов получения нештатного функционала.
    • Не рекомендуется писать код HTML в код PHP для изменения представления данных. В компонентах 2.0 разделены логика и представление. Логика — это сам компонент, представление — это шаблон вывода компонента. Шаблон существенно проще, чем компонент в целом. Нет необходимости изменять логику компонента для изменения особенностей показа его данных. Для одной логики может быть несколько представлений, в том числе зависящих от шаблона текущего сайта. Представление (шаблон вывода) может быть написано на любом шаблонном языке, который можно подключить из PHP. Например, шаблоны могут быть на PHP, Smarty, XSL и т.д.
    • Собственные компоненты и шаблоны — в собственном пространстве имен. Кастомизируя штатные компоненты и шаблоны, разрабатывая собственные, размещайте их в собственном пространстве имен. При обновлении системы все внесенные изменения в пространстве bitrix затираются.
    • При работе с компонентами не надо обращаться к базе напрямую. Концепция работы с продуктом предполагает работу с данными через функции API. Структура данных может меняться от версии к версии, а функции сохраняют обратную совместимость. Мы настоятельно не рекомендуем использовать прямые запросы к БД, т.к. это может нарушить целостность данных и привести к неработоспособности сайта. В силу вышесказанного структура таблиц не афишируется.
    • Не рекомендуется править код ядра в силу нескольких причин:
      • при обновлении системы внесенные изменения затрутся;
      • при изменении ядра владелец лицензии теряет право на техническую поддержку;
      • при изменении ядра разработчиком сайта возможна некорректная работа системы, так как ядро — сложная система, требующая учета работы всех модулей.

Выводы, которые я сделал, пережевав каждый пункт:

  1. В движке есть дохлый функционал, почему-то имеющий место быть.
  2. Не трогай, пока работает.
  3. Не лезь в код. В ЦСС лезь, больше никуда не лезь.
  4. Отсюда понятно, что мои таблички надо вкорячивать не на страницы, а в их шаблоны (логично). Интересно, но не стыкуется с остальными заповедями.
  5. Ваще никуда не лезь. Тыкай в веб-морду, но никуда не лезь.
  6. Не лезь в базу. Если очень надо — см.п.5.
  7. От слова «Ядро» у меня мурашки по коже. Пожалуй не буду лезть.

Ну чтож: Маркетплейс мне недоступен (лицензия потрачена), какой-то готовый модуль поставить не выйдет. Править существующие коробочные — не рекомендуется. Значит будем писать сами. Ушел курить маны. До связи!

Адаптивная фото-галерея на jQuery

Работая над сайтом-портфолио для своей Сестры, я встал перед очень тяжелым выбором: сверстать самому фото-галерею (слайдер) или же внедрить какой-либо готовый плагин.
Лень взяла верх, и я полез в интернеты в поисках того что нужно.
Краткое резюме: 8 часов впустую — мне ничего не понравилось…
Дальше время терять я был не намерен, и сел думать над алгоритмом:
Мне нужно окно 900х600 пикселей, с двумя кнопками «туда» и «сюда». В этом окне собственно и будут перелистываться фотки. А раз уж нужен адаптив — значит надо-бы сразу заложить реакцию на всячиские ресайзы экрана (а также перевороты устройства).
К делу! Разметка:

  <div class="fotobox"> 
    <div class="leftControl"><</div>
    <div class="rightControl">></div>
      <img src="https://kapu.cat/img/wlp/1.jpg">
      <img src="https://kapu.cat/img/wlp/2.jpg">
      <img src="https://kapu.cat/img/wlp/3.jpg">
      <img src="https://kapu.cat/img/wlp/4.jpg">
      <img src="https://kapu.cat/img/wlp/5.jpg">
      <img src="https://kapu.cat/img/wlp/6.jpg">
      <img src="https://kapu.cat/img/wlp/7.jpg">
  </div>

Тут все просто как 2 байта: контейнер Фотобокс, в нем две кнопки ЛефтКонтрол и РайтКонтрол, дальше внутри сами фотки. Фотки честно взял с яндекс-фоток.

Зададим сперва-сначала стили для самого бокса, приправив их медиа-запросами:

.fotobox{
  position: relative; /* позишн - релятиве */
  overflow: hidden; /*будем обрезать всё, что так или иначе не влезло*/
  background-color: #000; /* афро-американский фон*/
  text-align: center; /* так как фотки у меня в img а не всякими модными бэкграунд-аймэджами - это самый простой способ их отцентровать*/
  width: 900px; /*ну тут ясно*/
  height: 600px; /* тут тоже*/
  border: 1px solid black; /* на всякий случай*/
  border-radius: 10px; /* закруглим углы*/
  transition: all 1s; /* а вдруг анимация будет какая... пропишем уж сразу*/
}
@media screen and (max-width: 400px){ /*медиа-запрос под экраны мельче 400 пикселей (телефон в вертикальном виде, к примеру*/
  .fotobox{
  width: 300px;
  height: 200px;
  }
}
@media screen and (max-width: 700px){ /*тодж телефон в горизонтальном виде */
  .fotobox{
  width: 450px;
  height: 300px;
  }
}

Теперь стилизуем наши Лефт и Райт контролы:

/* кнопочки одинаково круглые, и имеют много общих черт, по этому стили одинаковые для обеих сразу*/
.leftControl, .rightControl{
 position: absolute; /* родитель - релятив, значит ребёнки - абсолют (чтоб разбежались в разны стороны потом)*/
  top: 40%; /* сверьху отступ*/
  z-index: 1; /* кнопки поверх фоток*/
  display: inline-block; /*на одной линии кнопки*/
  background-color: rgba(0,0,0,.5); /* полупрозрачные*/
  color: #fff; /* текст белый*/
  text-decoration: none; /* безо-всяких-там*/
  font-size: 40px; /* покрупней шрифт*/
  padding: 1.8% 3%; /* отступы */
  vertical-align: middle; // и шоб отцентровать на всякий случай*/
  cursor: pointer; /* чтоб обозначить кликабельность*/
  border-radius: 50%; /* скруглим квадрат*/
}
.leftControl{left: 1%;} /* а теперь одну кнопку влево*/
.rightControl{right: 1%;} /* а другую вправо*/
 
.leftControl:hover{ /* при наведении по-темней хай будет */
  background-color: rgba(0,0,0,.9);
}
.rightControl:hover{
  background-color: rgba(0,0,0,.9);
}

Ну и для самих картинок — ничего такого хитрого:

.fotobox img{
  width: auto;
  height: 100%;
  opacity: 0;  
}

Растягиваем по высоте во всю, а по длине уж как получится. Отцентруется — красиво будет.
— А прозрачность на нуль зачем? — спросите вы.
— Ведь ничего такого хитрого! Сам сказал! — скажете вы.

Едем дальше — в яваскрипт.
Для начала зададим ресайзы. Медиа-запросы — медиа-запросами, а с яваскриптом надежней имхо.

$(window).resize(function() {
  var boxW = parseInt($(window).width()); // ширину экрана измеряли
  if (boxW > 900) {
    $(".fotobox").css({ width: "900px", height: "600px" }); // если больше 900 - то вот так
  } else if ((500 < boxW) && (boxW < 900)) {
    $(".fotobox").css({ width: "450px", height: "300px" }); // если помельче - то сяк
  } else if (boxW < 500) {
    $(".fotobox").css({ width: "300px", height: "200px" }); // а если еще мельче то эдак
  }
});

Ну а теперь отрабатываем события нажатия на кнопочки и смену фоток (тут и прозрачность зачем была — поймете):

var $fotobox = $('.fotobox'), 
    $firstImg = $fotobox.find("img:first"), // узнаем кто первый в очереди
    $lastImg = $fotobox.find("img:last"); // и кто последний - тоже
 
$firstImg.css({'opacity' : '1'}) // первую фотку делаем видимой, остальные нет.
 
$('.rightControl').on('tap click', function(){ // кнопка вправо поехала:
   $fotobox.append($firstImg); // первую фотку вконец списка переместили
   $firstImg = $fotobox.find("img:first"); //запомнили что теперь первой стала вторая
   $lastImg = $fotobox.find("img:last"); // а последней первая
   $firstImg.css({'opacity' : '1'}) // новую первую сделали видимой
});
 
$('.leftControl').on('tap click', function(){ // кнопка влево поехала:
   $fotobox.prepend($lastImg); // крайнюю фотку сделали первой
   $firstImg = $fotobox.find("img:first"); // запомнили кто теперь стал первым 
   $lastImg = $fotobox.find("img:last"); // а кто крайним
   $firstImg.css({'opacity' : '1'})
});

Все оказалось не так страшно, и совсем не 8 часов… Осталось доработать событие свайпа и разворот в фулскрин.

Код можно пощупать 😉

See the Pen Gallery adaptiv by kapu (@kapu) on CodePen.0

Время чувственности

В конце прошлого года, где-то в середине ноября, мне прислали макет для печати на прозрачной пленке:

Эти часы накатывались на стеклянную витрину, на время какой-то акции одного популярного магазина женского белья.
Слоган меня поразил, как своей режущей взгляд и слух угловатостью, так и своей ТаймсНьюРомансностью. Но это не мое дело, раз макет утвердили, значит им так нравится. Единственное что я поправил перед печатью, не согласовывая с клиентом, это слетевший абрис в цифре 11.
Оригинальный слоган этой акции : Time to be Sexy. И я бы его не трогал, если честно…
Макет мне достался в кривых (там было 6 или 7 вариантов этих часов). И пока файлик риповался-печатался, я немножко оживил часы:

See the Pen Clock by kapu (@kapu) on CodePen.0

Анимация SVG на примере человечка

Я открыл Иллюстратор, и без каких-либо заморочек, нарисовал в нем человечка.
chel
Рисунок на уровне дошкольника, ну да и ладно 😉
Экспортировал в SVG отдельно туловище с головой, и отдельно левую руку. То есть, у меня получилось два SVG файла.
Оба элемента я прописал непосредственно в HTML. Каждому элементу присвоил свой ID («chubrik» для туловища, и «ruka» для руки). Для того, чтобы рука не находилась где-то под туловищем, необходимо обозначить позицию для обоих элементов:

svg {
position: absolute;
}

Далее, я указал, где же у руки та самая точка, во круг которой будет происходить вращение:

#ruka{
  transform-origin: left left;
}

Объявил правило, по которому будут происходить метаморфозы:

@keyframes move {
  0% { transform: rotate(-3deg) ; }
  25% { transform: rotate(0deg) ; }
  50% { transform: rotate(3deg) ; }
  75% { transform: rotate(0deg) ; }
  100% { transform: rotate(-3deg) ; }
  }

И вызвал это правило для нашей руки, указав характер и длительность анимации:

#ruka{
  transform-origin: left left;
  animation: move 1.5s linear infinite;
}

Итог:

See the Pen hello by kapu (@kapu) on CodePen.0

Лазерная гравировка на кожзаме

Кожзам, как и кожа — весьма легкоплавкий материал. Чтобы не испортить гравируемый предмет, необходимо серьезно подойти к сему мероприятию, начиная с подготовки изображения.

Я не буду рассказывать про настройку мощности, фокуса, скорости луча лазера, все станки разные, и каждый оператор по опыту знает, в каком режиме работать с материалом.

Ради этой заметки, я испоганил обложку своего старого ежедневника. Справедливости ради, стоит отметить, что гравировка выполнялась на «китайце», с мощностью луча 500 мвт. Выходное разрешение у которого 300 dpi.

К делу! Возьмем изображение и поглядим на него внимательно:oULM60d7jMQ

Мы видим весьма неплохую картинку, с линиями разной толщины, чоткими краями, безусловно контрастную, весьма и очень подходящую для гравировки. Для гравировки на чем угодно, кроме кожзама.

— Почему? — спросите вы.

— Слишком толстые линии, — отвечу я.

Еще раз вспомним, что кожзам очень и очень легкоплавкий материал. Линии такой толщины, даже в самом «аккуратном» режиме гравировки, будут чудовищно искажены и размазаны. Вот результат гравировки данного изображения без предварительной обработки.

IMG-20160902-WA0002

 

— А что же делать?

— В любом доступном редакторе упростить изображение до его контуров. Вот так:

oULM60d7jMQ2

Итог:

IMG-20160902-WA0001

 

Оба изображения наносились в одинаковых условиях, на одинаковых настройках станка.

 

Иконка vk.com для вордпресса

Добавил ссылки на социальные сети в футер блога. В корне темы есть svg файл, с иконками практически всех социальных сетей, на удивление даже codepen.io там оказался. Все ссылки которые я ввел, были подхвачены css скриптом темы, и установлены соответственные иконки автоматически (что удобно). Но там нет иконки Вконтакте =(
Вот так выглядело меню социальных ссылок, до моего вмешательства:
socOld
Что же делать? Не оставлять же вот так, как есть, люди не поймут с первого раза что это ссылка в вк, нужно внести ясность в происходящее… Так что делать? Дополнять/изменять svg файл? Искать у сапорта вк официальный логотипчик? Нет =) все проще =)
У кого нет этой иконки, делайте следующее:
1. Откройте style.css вашей темы,
2. Ctrl+F и ищите facebook, найдете сразу все правила для класса .social-navigation,
3. Добавляем правило для vk.com (просто заглавная буква В шрифтом Ариал Блэк):

.social-navigation a[href*="dropbox.com"]:before {
	content: "\f225";
}
 
.social-navigation a[href*="facebook.com"]:before {
	content: "\f203";
}
 
.social-navigation a[href*="vk.com"]:before {
	content: "B";
	font-weight: bold;
	font-family: Arial Black;
}

И вуаля, итог: soc

Кривой угол 90 градусов

В ходе работы над визуальным макетом пленочного раздела калькулятора, обнаружилась интересная задачка: необходимо загнуть уголок у пленки, но не нарисовать загнутый уголок в фотошопе, а именно загнуть его в пространстве!
Хватило бы и нарисованного уголочка, если бы в дурную голову не влетела гениальная мысль — когда пользователь выберет прикатку пленки на листовой материал, макет должен повернуться боком, показывая толщину и структуру материала! А когда макет поворачивается боком, с нарисованным уголочком… зрелище весьма ужасное…

Для реализации загнутого уголка, используются исключительно возможности CSS3, в частности — 3D трансформация.
Уголок реализован как квадрат, одна половинка которого — абсолютно прозрачна, а вторая — и есть наш уголок.
После получаса игры с градусами наклона, и кручения в руках транспортира, в мою голову все равно не уложилось — почему при угле поворота по оси Z на 90 градусов, остается зазор, между уголком и плоскостью-родителем?

See the Pen QNJvaM by kapu (@kapu) on CodePen.0

Ну и на закуску ищущим готовое решение загнутого уголка в 3D средствами CSS, вот код моего макета со всеми тенями.

See the Pen NNoLgE by kapu (@kapu) on CodePen.0


На вопрос, почему квадрат-уголок повернут именно на 206 градусов по оси X и на 24 градуса по оси Y отвечу — для приближения сего макета к реальности. Если нажать кнопочку «прозрачная пленка» — картинка на уголке будет выглядеть именно так, как она должна выглядеть, если отогнуть уголок у прозрачной пленки в реальной жизни.