Задача: Узнать идентификатор страницы в WordPress.
Что такое идентификаторы Страниц и Записей в WordPress? Это их числовые уникальные номера, которые не могут быть идентичными.
То есть, если создать две одинаковые страницы, например, страница «О нас» и точно с таким же заголовком вторую страницу «О нас», и наполнить их одинаковой информацией, то что мы получим?
Для пользователя это будут визуально абсолютно одинаковые страницы, а для CMS WordPress — разные. При создании каждой из страниц будет присвоена уникальная цифра, которая и называется — «айдишником» (идентификатором этой страницы), именно по ней WP и различает их.
Можно рассмотреть пример из жизни. Рождаются два близнеца, да таких, что мать родная не различит. Им выдаются разные свидетельства, паспорта. Что в итоге? Близнецы на вид одинаковые, а паспорта разные — для того чтобы отличать их друг от друга в системе Жизнь. Так и со страницами. Не может быть одинаковых номеров.
Решение:
Способ №1
Если вы находитесь в панели управления WordPress с привилегиями, позволяющими видеть, редактировать контент сайта, то в разделе Страницы нужно навести на нужную вам страницу курсор мышки и не отводя его, посмотреть в нижнюю часть, там должна отобразиться ссылка, в которой и будет содержаться идентификатор страницы.
В данном примере id=54
Это справедливо и для Записей, по сути это те же самые страницы. Переходим в раздел всех Записей и наводим курсор на нужную:
В этом примере ID страницы равен 1.
Способ №2
Выяснить идентификатор страницы (или Записи) можно в режиме её редактирования. То есть, переходим в режим редактирования (это когда открыт визуальный редактор этой страницы) и обращаем внимание на ссылку в верхней части:
Видим, что id-53
Способ №3 (с публичной части сайта)
В принципе, рассмотренных вариантов из панели управления достаточно, чтобы быстро идентифицировать страницу. Но как быть, если вы находитесь на сайте, как пользователь, а не как администратор?
В этом случае будет чуть-чуть сложнее. В рассматриваемом примере я использую браузер Google Chrome. Нам нужно находиться именно на той странице, «айди» которой мы желаем выяснить.
Я перехожу на страницу Контакты и нажимаю правой клавишей мышки в любой её области. Затем, нужно открыть Просмотр кода страницы (в разных браузерах может по-разному это называться), или воспользоваться комбинацией горячих клавиш Ctrl+U
В исходном коде попытаться найти какие то упоминания об id. Как правило, это упоминание должно с очень большой долей вероятности находится в теге <body>
Задача: На странице оформления заказа в поле для ввода номера телефона задать предустановленную схему номера в формате пригодному для русскоязычного сегмента
+7 xxx-xxx-xx-xx (или вариант через 8-ку)
Решение: Выполнять поставленную задачу мы будем на JavaScript, в первом случае — на базе библиотеки jQuery, которая поставляется с WordPress и доступна «из коробки» и во-втором — решение на нативном JS (то есть без зависимостей от сторонних библиотек, в частности jQuery)
Мне встретилось в интернете уже готовое решение, поэтому придерживаясь принципа: «Зачем писать то, что уже написано», я взял его за пример. Единственное, нужно проинспектировать нашу форму отправления заказа и выяснить идентификатор нашего «инпута» для указания номера телефона.
Давайте взглянем на форму при оформлении заказа в WooCommerce.
Если требуется добавить в поле подсказку какой формат ввода номера телефона мы ожидаем от пользователя, то поможет нам в этом специальный фильтр, который отвечает за возможность изменения информации в полях. В документации есть подходящий для решения нашей под-задачи пример
// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['order']['order_comments']['placeholder'] = 'My new placeholder';
$fields['order']['order_comments']['label'] = 'My new label';
return $fields;
}
В примерах из документации можно найти все названия полей. В нашем случае идентификатор нашего поля billing_phone (смотреть рисунок выше, с исследованием элемента) и он относится к группе Billing (эта информация получена тут). Поэтому наш код будет выглядеть следующим образом:
// Hook in
add_filter( 'woocommerce_checkout_fields', 'poet_override_checkout_fields' );
function poet_override_checkout_fields( $fields ) {
$fields['billing']['billing_phone']['placeholder'] = '+7 (123) 456-78-90';
$fields['billing']['billing_phone']['maxlength'] = 10; // ожидаем ввода 10 основных символов номера телефона
return $fields;
}
Выполнение данного кода привнесло в поле нашей формы подсказку-заполнитель
Естественно, мы не можем ручаться что именно так будет осуществлён ввод данных пользователем. Поэтому напишем вторую функцию, которая будет задавать правильное форматирование при вводе благодаря шаблону, который мы реализуем.
В WooCommerce для этого есть удобная функция wc_enqueue_js(), которая добавляет пользовательский код в вывод в нижней части сайта перед закрывающим тегом </body>. Вывод справедлив если страница каким то образом относится к WooCommerce. То есть на одиночной странице записи этого вывода не будет.
Найти функцию можно от корня вашего сайта в wp-contents/plugins/woocommerce/includes/wc-core-functions.php
Она позволяет добавлять в глобальную переменную (global $wc_queued_js) произвольный код. А её вызов можно увидеть чуть ниже по коду:
Обратите внимание, что обёртка для jQuery уже присутствует и можно просто пользоваться её методами. И вот изящное решение, от Rodolfo Melogli можно увидеть ниже.
Оно рабочее. Но зависит от библиотеки jQuery и «заточено» под американский стандарт, так сказать. Так же данное решение не сработает на страницах, которые не относятся к WooCommerce (справедливо для данного кода выше). Ещё мне не нравится пример заполнителя, пользовательский опыт говорит об обратном, вряд ли все будут придерживаться строгого заполнения.
Можно конечно доработать и всё исправить (в случае с примером выше основанным на jQuery), но мне больше понравилась библиотека Cleave.js и её аддон, который заточен под русские стандарты при вводе номера телефона, учитывая с «восьмёрки» или с «плюс, семёрки» начинает набирать пользователь номер.
Поэтому в данном примере мы подключим саму библиотеку и её аддон для страны с кодом RU (в целях уменьшения размера подключаемого кода) и проверим его работу в действии.
К тому же, подключать мы будет стандартной функцией WP для того чтобы решение было универсальным и могло использоваться на разных страницах к разным формам, в том числе популярного плагина Contact Form 7.
Важное примечание! Библиотека с минувшей осени (обращение автора от 25.11.23г) уже не поддерживается по ряду причин, которые описаны в обращении. Она переписана автором на TypeScript и ES6. Пример в статье просто иллюстрирует решение задачи. В целом рекомендуется эта библиотека.
Первым делом задействуем старую добрую функцию WP wp_enqueue_script(), которая будет подключать скрипт библиотеки Cleave.js и её аддон ориентированный на RU. Проверка ! is_checkout() гарантирует подключение только на странице оформления заказа и исключает подключение на прочих страницах
wp_add_inline_script( ‘cleave-phone’… инициализирует (вызывает функционал) на нужном нам поле с нужными параметрами, а частности разделителем в виде чёрточки.
Результатом выполнения кода будет предопределённая маска, которая не позволит пользователю вводит через чур много символов и будет учитывать начало ввода «+7» или «8»
Как подключить маску на других страницах, к другим формам?
Всё очень просто. Решение универсальное в пределах WP.
У нужной формы необходимо понять, как «зацепиться» за нужное поле, или «по айди» или «по классу»
Узнать «айди» страницы, для того чтобы добавить её в условие проверки, дабы не вызывать где не попадя 🙂
Например, у нас есть форма для обратной связи на странице контактов. Первым делом исследуем нужное поле:
Видим подходящий класс. Следовательно, понимаем, как будем делать «селект» — по классу. Далее, узнаем «айдишник» страницы на которой наша форма. В итоге наш код может выглядеть так:
Из примера видно, что мы просто, через запятую, добавили новый селектор по CSS классу. Теперь наша маска применяется к полу телефона созданной плагином Contact Form 7
Рекомендация. Старейтесь всегда проверять исходный код страницы и убеждаться, что нужный скрипт присутствует на ней.
WooCommerce– это платформа электронной коммерции для WordPress с открытым исходным кодом, которая предоставляется в виде плагина совершенно бесплатно для всех желающих превратить свой сайт на WordPress в интернет-магазин.
Частой задачей (и крайне важной для маркетологов) является передача с заказом информации чтобы отследить эффективность рекламной кампании.
Хорошая весть! В WooCommerce с версии 8.5 наконец-то появился механизм который делает захват данных (GET-параметры из URL и прочие данные из Заголовков ответа сервера), сохраняет их и передаёт с выполненным Заказом. Тем самым мы можем получить очень важную информацию об эффективности той или иной рекламной кампании.
Ещё раз отмечу, что это доступно с версии 8.5.
Как узнать какая у меня версия WooCommerce?
Для этого нужно перейти в раздел WooCommerce > Статус
На данном примере версия ниже 8.5 и как следствие этой настройки мы не обнаружим
Как задействовать (включить) эту функцию?
Для того чтобы включить (или проверить включено-ли) эту новую функцию передачи данных UTM-меток, нам необходимо пройти в раздел WooCommerce > Настройки, далее вкладка Дополнительно и выбираем её подраздел Функции:
И нужно включить функцию Атрибуция заказа. Что произойдёт? Теперь при оформлении Заказа в теге <form> появятся скрытые поля со служебными данными:
Если у вас уже были «прикручены» скрытые поля в форме, то полагаю совместимость будет хорошая, так как атрибут name задан очень уникально )
Как это работает?
В частности UTM-меток, в ядре WooCommerce для клиентской части (frontend) есть sourcebuster.js скрипт, который и забирает значения из нужных GET-параметров, то есть ссылки должны быть сгенерированы классическим образом и названия должны быть стандартные. Разобраться в этом и сформировать правильный URL поможет, например, этот конструктор.
Обязательные параметры:
utm_source — название рекламной площадки
Зачем нужен: Чтобы указать название источника трафика
Примеры:
utm_source=google – контекстная реклама в Google Ads
utm_source=yandex — контекстная реклама в Яндекс.Директ
utm_source=vk — контекстная реклама в Вконтакте
https://tilda.cc/ru/utm/
utm_medium — тип рекламы
Зачем нужен:
Чтобы определить типа кампании или рекламы
Примеры:
utm_medium=organic – бесплатный переход
utm_medium=cpc – контекстная реклама (cost per click, плата за клик)
utm_medium=email — рассылка
utm_medium=social — социальные сети
utm_medium=banner — медийная реклама
utm_medium=cpa — другая реклама (cost per action, плата за действие)
https://tilda.cc/ru/utm/
utm_campaign — название кампании
Зачем нужен:
Позволит вам отличить одну рекламную кампанию от другой в статистике
Примеры:
utm_campaign=mebel_dlya_doma – рекламная кампания мебели для дома
https://tilda.cc/ru/utm/
Необязательные параметры
utm_content — дополнительная информация, которую можно отслеживать, если совпадают другие параметры
Зачем нужен:
Часто используется как пометка для объявления внутри рекламной кампании. Название можно задать произвольно, удобнее всего использовать важные характеристики объявления — подкатегория товара или услуги, тип самого объявления и т. п.
Примеры:
utm_content=zero_block240×60 — баннер 240 на 60 про Zero блок на Тильде
utm_content=zero_block_text — текстовое объявление про Zero блок
https://tilda.cc/ru/utm/
utm_term — ключевое слово, с которого начался показ объявления
Зачем нужен:
Позволит вам отличить одну рекламную кампанию от другой в статистике
https://tilda.cc/ru/utm/
Я заполнил параметры нужными значениями и получил готовую ссылку:
Теперь при переходе по ней скрипт (sourcebuster.js) будет забирать значения из нужных параметров в URL и сохранять их в браузере. А в момент заказа обращаться к ним и добавлять в форму для отправки.
Данные передаются в объекте Заказа и сохраняются в БД. Доступ к этим данным можно получить в карточке заказа.
В таблице всех заказов вы должны увидеть столбик важных данных — Происхождение. На мой взгляд понятнее было бы назвать Источник, но не суть …
Если вы не видите этот столбик, то проверьте в настройках экрана включен ли он у вас?
Ну а если мы «провалимся» в карточку отдельного заказа, то в разделе Атрибуция Заказа увидим намного больше полезной информации о нашем заказчике:
Обратите внимание, на информацию о Типе устройства клиента. В некоторых случаях это может быть очень полезно.
Нюансы
Так как разработчики плагина WooCommerce делают акцент на блочную парадигму разработки, то представление нашей страницы Оформления заказа теперь может иметь блочный вид. В режиме редактирования страницы, которая отвечает за Оформление заказа можно увидеть два варианта отображения:
Классический — это при помощи шорткода, который вызывал функционал подключения тэмплейтов и т.п.
Блочный — на базе блоков редактора Gutenberg.
Если удалить это элемент и попытаться найти новый, то нам будет доступен ещё один вариант — блочный:
Добавив его, мы получаем довольно красивый шаблон для клиентской странице оформления заказа:
В этом случае исследование элементов формы могут вас расстроить, так как вы не обнаружите скрытых полей в виде элементов <input> , но не стоит расстраиваться! Они присутствуют, правда в другом формате — в виде объекта JSON
Вот, после отправки из блочного представления Оформления Заказа получили ожидаемые данные:
Важное примечание. Эти UTM-метки и прочие данные хранятся в течении сеанса пользователя. То есть, после того, как посетитель прекращает сессию, тем самым закрыв окно браузера, то эти данные уничтожаются.
Что хранится в файлах cookie?
Функция атрибуции заказов использует следующие файлы cookie:
Имя файла COOKIE
Данные
Срок Хранения
sbjs_session
Количество просмотров страниц в текущем сеансе и путь к странице.
30 минут
sbjs_udata
Информация о посетителе, такая как IP, браузер и тип устройства.
Сессия
sbjs_first
Источник трафика первого посещения посетителем вашего магазина
Сессия
sbjs_current
Источник трафика
Сессия
sbjs_first_add
URL-адрес и страница входа для первого посещения посетителем вашего магазина
Сессия
sbjs_current_add
URL-адрес и страница входа для текущего посещения посетителем вашего магазина
Сессия
sbjs_migrations
Прочие Технические данные
Сессия
Какие данные получает Automattic?
Учтите, что эти данные для внутренних целей может получать компания-разработчик продукта WooCommerce. В компанию Automattic будут передаваться данные каждого заказа с вашего сайта. Данные клиента, такие как адрес электронной почты, платежные данные или данные о доставке, переданы не буду.
Если вы не желаете передавать эти данные в Automattic, то нужно убедиться в том, что функция отключена (галочка должна быть снята)
Эта заметка относится к разряду технической. То есть уже требует небольшого погружения в код .
Дано: Сайт под управлением CMS WordPress.
Задача: Проверить на уровне сервера (на стороне back-end) данные приходящие извне, на корректный номер телефона.
Решение: Если у вас установлен плагин для электронной коммерции WooCommerce, то обращу внимание на то, что в нём уже существует специальный метод (функция) который позволяет осуществить проверку на корректный номере телефона, то есть исключить обработку данных, если в них содержаться какие то иные символы, например, буквы.
Давайте взглянет на класс WC_Validation. В нём мы увидим нужные нам методы для решения поставленной задачи:
is_phone() — Проверяет номер телефона с помощью регулярного выражения.
format_phone() — Позволяет отформатировать переданный номер телефона.
Давайте взглянем на этот метод из ядра плагина WooCommerce:
/**
* Validates a phone number using a regular expression.
*
* @param string $phone Phone number to validate.
* @return bool
*/
public static function is_phone( $phone ) {
if ( 0 < strlen( trim( preg_replace( '/[\s\#0-9_\-\+\/\(\)\.]/', '', $phone ) ) ) ) {
return false;
}
return true;
}
Очевидно, что метод реализует грамотную проверку на адекватный номер телефона.
Функция strlen() возвращает длину строки и тут же мы её проверяем , чтобы она не была меньше нуля. А функция trim() ещё раньше отрабатывает и её назначение — удалить пробелы из начала и конца строки. И в серединке мы видим функцию preg_replace(), которая осуществляет поиск и замену по регулярному выражению. Первый аргумент — это паттерн. Второй аргумент — это то, что функция получает, то есть наш номер телефона извне. Возвращает функция булев тип: true|false.
Применение:
В принципе, для того чтобы воспользоваться функцией можно просто вызвать её, передав ей данные на валидацию. Но я предлагаю другой подход. Мы её вынесем отдельно, как функцию-хелпер, но только с проверкой на объявление одноимённой функции (можно конечно просто переименовать произвольно и не заморачиваться, но я учёл, что может быть активирован плагин Woo и тогда выполнение вызова функции, будет уже на стороне Woo).
/**
* Validates a phone number using a regular expression.
*
* @param string $phone Phone number to validate.
* @return bool
*/
if (!function_exists('is_phone')) {
function is_phone( $phone ) {
if ( 0 < strlen( trim( preg_replace( '/[\s\#0-9_\-\+\/\(\)\.]/', '', $phone ) ) ) ) {
return false;
}
return true;
}
}
Я специально подготовил данные с разными вариантами: слитно со знаком «плюс», с чёрточками и с пробелом (последний пример). Люди по разному могут указать номер телефона. Все примеры валидны.
А теперь давайте рассмотрим не валидный пример, в котором специально вместо нуля передал заглавную «O», а в двух следующих специальные символы, которые не учтены в паттерне регулярного выражения. В итоге получили false
Форматирование номера телефона
Вторая функция format_phone(), которая идёт «прицепом» к первой, является обёрткой функции wc_format_phone_number()
Обратите внимание, что внутри после проверки на пустую строку идёт проверка и привязка к ранее рассмотренной функции. Согласно коду — это метод класса WC_Validation и он должен быть не false. Тогда то и происходит магия при помощи регулярного выражения и другого паттерна. Задумка хорошая, но по большому счёту для нашего континента бесполезная 🙂
При желании можно конечно «допилить» это дело, например, оформить в отдельную функцию-хелпер или же дополнить код первой функции и получить полное решение валидации номера телефона с последующим форматированием при возврате функцией. Хорошей отправной точкой тут может послужить нативная функция PHP sscanf() — которая разбирает строку в соответствии с заданным форматом. Вот пример со страницы описания данной функции.
Естественно, что для начинающих пользователей это может показаться сложным решением, поэтому я предлагаю написать простенькую «функцию-прицеп» к нашей первой функции-валидатору, которая будет возвращать отформатированную строку.
Код не идеальный. Это просто импровизация для того чтобы показать, как просто на стороне «бэкэнд», на PHP можно сделать форматирование возвращаемой строки с номером телефона.
Здесь для демонстрации возможностей PHP для каких-то проверок/условий задействовал функцию iconv_strlen() — возвращает количество символов в строке, а не количество байт (как, например strlen()).
Если отталкиваться от этого кода, то тут нужно учесть, что первая наша функция разрешает символы «+» и «-» , а следовательно их подсчёт тоже будет учитываться и нас подстерегает неожиданность при форматировании 🙂 Поэтому, в этом случае имеет смысл передавать только цифры, а всё лишнее — вычищать. Следовательно, наше выражение может иметь в первой функции следующий вид:
preg_replace("/[^0-9]/","", $phone ........
Но тут опять много нюансов, например человек может начать запись с «8-ки», а может с «7-ки» 🙂 А в Казахстане формат встречается зачастую +7 (7xx) xxx-xx-xx
Поэтому можно сохранять в базу значение до форматирования, а потом ещё и после и в случае каких-то непонятных ситуаций исследовать эти значения.
В общем, если подытожить, то на мой взгляд первой функции вполне достаточно. Главную задачу она выполняет — чистка пробелов и прочих лишних символов, которые никак не ассоциируются с записью телефонного номера.
Но, если вы всё-таки намерены делать форматирование, то я предлагаю реализовать его на стороне клиента и для этого можно задействовать изящное решение под WooCommerce, при помощи которого мы можем задать нужную маску для ввода номера телефона пользователем перед тем, как он будет передаваться функции-валидатору.
Прежде всего стоит осознать, какую угрозу для вашего SEO (поисковая оптимизация сайта) несут неработающие (битые) ссылки внутри вашего веб-сайта.
Распознать такую ссылку очень легко. Как правило, переход по ней приводит на страницу со статусом ошибки 404.
При взаимодействии пользователей с вашим сайтом, это влечёт для них негативный опыт и как следствие понижение в выдачи поисковых систем страниц вашего сайта. Ведь зачем показывать Яндекс и Google URL с вашего веб-сайта на первых позициях, если пользователи не смогут получить нужную им информацию. Согласны?
Отсюда, индекс качества таких URL понижается и они попросту теряются. Вероятность, что кто то попадёт на такие страницы (со статусом 404) из поисковой выдачи очень мала.
Как обнаружить неработающие ссылки?
Для этих целей существуют различные инструменты: Google Search Console, Screaming Frog, Яндекс Вебмастер и другие. В Яндекс Вебмастере относительно недавно, появился новый инструмент для проверки ссылок с ошибками.
С помощью «Вебмастера» вы можете определить неработающие ссылки:
внутренние — это ссылки, ссылающиеся между страницами вашего сайта;
внешние — это ссылки, ведущие на ваш сайт со страниц других ресурсов;
исходящие — это ссылки, которые ведут со страниц вашего сайта на другие ресурсы.
Выглядит это так:
Внутренняя ссылка — это ссылка, которая расположена на странице вашего сайта и ведет на другую страницу этого же сайта.
Неработающие внутренние ссылки могут отрицательно влиять на удобство сайта, если они мешают навигации посетителей по страницам сайта.
Ссылка считается неработающей, если на запрос робот получил HTTP-статус отличный от 2XX или 3XX.
Неработающие ссылки могут быть исключены из индекса. Информация об этом доступна в разделе «Статистика обхода».
Сведения о работоспособности ссылки обновляются в сервисе после переиндексации роботом.
Плагин для проверки битых ссылок Broken Link Checker (автор: WPMU DEV)
Если по каким то причинам вы не желаете использовать отличный сервис Яндекс Вебмастер или схожие, то можно воспользоваться решением в виде плагина для CMS WordPress.
После установки плагина, работу с ним начать можно сразу из меню Проверка ссылок:
Перед нами дилемма: или начать работу в «облаке», либо «по старинке» за счет вычислительных мощностей вашего сервера и интерпретатора PHP 🙂
Первый метод требует создание аккаунта на сервисе разработчиков, поэтому я предпочёл выбрать второй вариант — Локальный.
Стоит отметить, что плагин работает сразу «из коробки», то есть уже начинает анализировать ваш контент на предмет битых ссылок. В данном примере видно, что сразу найдено 9-ть неправильных ссылок и 741 URL в очереди на проверке. Неплохое начало)
Тут же мне посыпались уведомления (на E-mail администратора), о том что были найдены битые ссылки. В скриншоте выше видно, что уведомлениями мы можем управлять и при необходимости отключить их или изменить получателя. А вот и скриншот письма:
Вобщем, при локальном методе работы, наш плагин содержит две вкладки: Обнаруженные ссылки и раздел настроек:
Давайте прежде разберёмся, что делать с неработающими ссылками, а потом немного рассмотрим настройки плагина.
Как исправить битые ссылки?
Всё зависит от назначения ссылки. Ситуации бывают разные. Рассмотрим один интересный кейс (случай):
Ссылка на сайте долгое время вела на каталог в формате PDF (кстати, такие файлы тоже индексируются и могут быть доступны для поиска пользователям в Google, Яндекс или других поисковых машинах).
Вот баннер, который располагается на главной странице сайта.
Клик по баннеру перенаправляет пользователя на каталог в виде файла формата PDF
Этой ссылкой, на этот файл много делились в социальных сетях, многие из дилеров или дизайнеров интерьеров оставляли на него закладку в своём браузере, чтобы быстрее возвращаться к нему при работе с клиентами, в момент предложения интерьерных решений, например.
И вот в один прекрасный день, кто-то по ошибке, а может и нарочно удаляет с сервера этот файл. Что произойдёт? Все кто будет переходить по этому УРЛ будут непременно видеть:
Знакомая картина?
Поэтому, конечно же необходимо проверять свой сайт на предмет неработающих ссылок, наверняка этот аудит принесет не мало удивлений вам 🙂 По крайней мере можно вовремя исправить неприятность, такую которую мы сейчас рассматриваем в этом примере.
Итак, как исправить эту неработающую ссылку? Естественно загрузить новый файл с точно таким же названием, либо сделать перенаправление на другой файл или страницу. Тем самым мы не потеряем потенциальных клиентов, которые перейдут по этой ссылке, понимаете?
Другой случай. Была удалена неактуальная статья с сайта. А на эту статью ссылались другие страницы сайта, условно говоря, была перелинковка. Что делать в этом случае? Естественно исправлением будет — удаление ссылок на эту страницу, так как новую создавать не планируется, в силу неактуальности информации.
Поэтому, тут всё индивидуально. Смотря какая ситуация будет у вас. В основном это следующие решения:
Настройка переадресации (301) на похожие страницы сайта
Исправление ссылки на новую (действующую)
Удаление неисправных ссылок
Настройки плагина
В разделе настроек хотел бы отметить следующие возможности:
Настройка уведомлений об обнаружении битых ссылок на вашем сайте
Периодичность проверок (по умолчанию 72 часа). Если контент на вашем сайте редко меняется, то можно значительно увеличить этот интервал.
Можно указать тип контента по которому осуществлять поиск. В частности, если у вас интернет-магазин, то возможно будет разумным включить поиск по типу контента — Товары.
Показать виджет панели инструментов для… И по умолчанию стоит настройка «Редактор и выше». Возможно, стоит ограничиться только ролью Администратора
«Поковыряйтесь» обязательно в настройках, вполне возможно некоторые из них вас приятно удивят.
Чтобы получить информацию о структуре таблицы, задействуем оператор DESCRIBE; который отобразит инфу о каждом столбце таблицы (в моём примере это таблица wp_posts):
mysql> DESCRIBE wp_posts;
Результат выполнения:
+-----------------------+---------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------------+------+-----+---------------------+----------------+
| ID | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| post_author | bigint(20) unsigned | NO | MUL | 0 | |
| post_date | datetime | NO | | 0000-00-00 00:00:00 | |
| post_date_gmt | datetime | NO | | 0000-00-00 00:00:00 | |
| post_content | longtext | NO | | NULL | |
| post_title | text | NO | | NULL | |
| post_excerpt | text | NO | | NULL | |
| post_status | varchar(20) | NO | | publish | |
| comment_status | varchar(20) | NO | | open | |
| ping_status | varchar(20) | NO | | open | |
| post_password | varchar(255) | NO | | | |
| post_name | varchar(200) | NO | MUL | | |
| to_ping | text | NO | | NULL | |
| pinged | text | NO | | NULL | |
| post_modified | datetime | NO | | 0000-00-00 00:00:00 | |
| post_modified_gmt | datetime | NO | | 0000-00-00 00:00:00 | |
| post_content_filtered | longtext | NO | | NULL | |
| post_parent | bigint(20) unsigned | NO | MUL | 0 | |
| guid | varchar(255) | NO | | | |
| menu_order | int(11) | NO | | 0 | |
| post_type | varchar(20) | NO | MUL | post | |
| post_mime_type | varchar(100) | NO | | | |
| comment_count | bigint(20) | NO | | 0 | |
+-----------------------+---------------------+------+-----+---------------------+----------------+
23 rows in set (0.00 sec)
В этой статье обсудим архивацию данных — частая и весьма полезная операция любого разработчика или системного администратора.
Начнем мы с алгоритма .zip и неспроста. Данный формат очень популярен и является универсальным для многих операционных систем, будь то Windows или MacOS — а это значит, что полученный zip-архив сможет распознать (зачитать) почти любая операционная система.
Отмечу, что архивация и сжатие — это разные понятия. Это небольшое примечание не играет в нашей статье особой роли, но желательно сразу эти термины разделять.
Задача: Архивировать файлы в архив ZIP, определённой директории на сервере, для дальнейшей работы с их копией в заархивированном виде.
Решение: Первым делом нам нужно проверить наличие пакета zip для дальнейшей работы. В этом нам поможет пакет dpkg — менеджер пакетов для Debian.
Чтобы получить подробный отчёт о состоянии определённого пакета, выполните команду:
dpkg --status zip
или при помощи инструмента dpkg-query — чтобы сделать запрос в базу данных пакета dpkg
dpkg-query -s unzip
Ключ -s это сокращение от —status
Вот пример выполнения запроса на боевом сервере одного из моих заказчиков:
Мы видим, что пакет для архивации данных zip отсутствует в нашей ОС. А в свою очередь следующий запрос, который я сделал для разнообразия по второму примеру в коде выше, выдаст нам противоположный результат. Мы видим, что пакет unzip существует в нашей ОС:
Для разнообразия, можно было осуществить проверку следующей командой:
zip --version
Следовательно, если пакет отсутствует, то требуется его установка в нашу ОС:
sudo apt install zip
Если отсутствовали оба пакета, то можно исправить эту неприятность вот такой командой:
sudo apt install zip unzip
Архивация пакетом zip
Подготовительная часть позади и теперь мы можем перейти непосредственно к выполнению поставленной задачи. Файлы, которые нам нужно заархивировать находятся в директории /var/www/site
cd /var/www/site
Убедимся, что мы находимся в нужной директории и в ней находятся нужные для архивации файлы. Воспользуемся для этого командой ls или dir. Вывод файлов после выполнения:
Перейдем непосредственно к делу и нехитрой командой сделаем наш архив:
sudo zip -r archive.zip *
Произойдёт магия… и после выполнения, введя повторно ls — выводит содержимое каталога, мы должны обнаружить наш архив
Разберёмся в этой магии…
ключик -r предписывает утилите zip рекурсивно проходить все директории и архивировать их содержимое. А звездочка в конце команды — равносильно слову «ВСЁ», т.е. — архивировать всё, что есть в директории, в которой мы и находимся.
Как вариант можно указать путь к той директории которую мы архивируем. Это полезно когда вы находитесь в другом месте в системе и вместо звездочки просто указываете нужный, относительно корня ОС, путь:
zip -r filename.zip /path/to/folder
## Наш пример
zip -r archive.zip /var/www/site
Рассмотрим более сложный пример, в котором мы добавим в архив изображения с расширением файлов: .jpg, .jepg, .png
zip -R archive_image "*.jpg" "*.jepg" "*.png"
В архив archive_image.zip попадут картинки с перечисленными расширениями. Учтите, что в архив попадает и структура директорий:
В принципе, на этом всё. Да, есть много нюансов при работе с zip, таких как: включение в архив только нужных типов файлов (используется ключ -i), можно указать степень сжатия по шкале от 0 до 9, где 0 — это отсутствие сжатия, можно при помощи параметра -P задать пароль на архив. Но все это уже частные случаи.
Разархивирование данных происходит проще простого. Вместо команды zip нам следует использовать — unzip. Пакет unzip — это распаковщик файлов .zip
И перед распаковкой, начать стоит с проверки целостности данных. Это осуществимо при помощи ключика -t (test). Обратимся к нашему архиву указав следующую команду:
unzip -t archive.zip
Данный синтаксис подразумевает, что вы находитесь в той же директории где и ваш архив. В противном случае необходимо указать относительный путь, например:
unzip -t /var/www/site/archive.zip
Результат выполнения:
Убедившись в отсутствии ошибок, мы приступаем к разархивированию данных. И здесь нам необходимо придерживаться правила ЧТО / КУДА.
То есть первый путь мы задаем то ЧТО подлежит разархивированию, а второй — КУДА требуется выгрузить файлы из архива. Единственное что нужно тут учесть, так то, что после архива мы указываем ключик -d (директория) и далее путь к папке куда произойдет разархивация:
unzip /var/www/site/archive.zip -d /var/www/html
Эта инструкция распакует наш архив в директорию html. На скриншоте ниже можно посмотреть как отработала эта строка. В данном примере, мы подымаемся на уровень выше из директории site, далее выбираем директорию html и смотрим её содержимое. Файлы из архива на месте!
Если вы забыли ( добро пожаловать в клуб ? ), что находится в вашем архиве, то его содержимое можно посмотреть при помощи параметра -l (list)
Задача: на странице вариативного товара установить предпочтительное значение вариации (опции) по умолчанию
Решение: Нужно зайти в режиме редактирования на карточку вариативного товара и в разделе Вариации выбрать нужный вариант, который будет отображаться по умолчанию вместо слова Выбрать
Допустимы и комбинированные варианты, когда вариация создаётся на основе двух и более вариантов
Дано: Интернет магазин под управлением WordPress + WooCommerce.
Задача: Отследить успешное добавление товара в корзину пользователем и передать эту информацию для аналитики в Яндекс Метрику.
Решение: решить подобную задачу можно разными способами: на стороне клиента, исключительно за счёт JavaScript и на стороне сервера — на PHP.
Требования к сайту
При создании цели важно учитывать:
Форма должна быть создана с помощью тега form. Если форма сделана через теги div, она отслеживаться не будет.
Отправка формы должна выполняться через элементы button type=»submit» и input type=»submit». Если отправка реализована через элемент button type=»button», цель достигаться не будет.
Элементы button type=»submit» и input type=»submit» должны находиться внутри элемента form.
Если форма обрабатывается с помощью JavaScript, цель будет работать только для стандартного события onSubmit.
Так как вёрстка в разных шаблонах оформления может быть разная, то своё решение мы начнём с исследования нашей кнопки в объектной модели документа (DOM), для того что бы понять удовлетворяет ли наш сайт описанным условиям.
Мы видим элемент кнопки (button) и наличие атрибутов, которые могут помочь «зацепиться» за этот элемент и «повешать» на него нужное нам событие. Также наша кнопка находится в теге <form> , что говорит о соответствии условиям описанных в документации Яндекс Метрики.
Забегая вперёд отмечу, что для точности передачи данных лучше вешать это событие на отправку формы, а не на клик по кнопки (хотя для некоторых задач подойдет именно клик, например, когда вы хотите просто проверить интерес к чему либо, к новому разделу на сайте).
Первым делом, нам нужно создать цель в личном кабинете Яндекс Метрики:
Выбираем JavaScript-событие и присваиваем этому событию уникальное имя для дальнейшего отслеживания. В примере ниже, мы можем наблюдать, как после создания идентификатора цели ниже, мы можем наблюдать готовую строку кода, который необходимо будет вызвать на наше событие:
Готово! Часть задачи мы выполнили. В личном кабинете Яндекс Метрики создана наша цель:
Решение на JavaScript
Теперь, мы можем смело приступать к дальнейшей реализации на стороне сайта.
В качестве селектора (выбираемого из DOM элемента) у нас выступает тег form с классом «cart». Наш скрипт может выглядеть примерно так:
Пояснение: мы получили наш элемент формы и наблюдем через подписку на событие submit за её успешной отправкой (добавление в корзину — это и есть в нашем случае отправка формы)
Если приглядеться к примеру указанному на сайте Яндекс Метрике, то мы можем заметить, что можем разместить вызов функции Яндекс Метрики (ym) прописав его в атрибут onsubmit нашей формы добавления товара в корзину.
Если вы всё сделали правильно, то при исследовании элемента непременно должны увидеть добавленный атрибут (справедливо для варианта №2)
Теперь в Яндекс Метрике, в разделе Конверсии, мы можем ожидать результат её выполнения:
Вот так выглядит выполнение скрипта (цель отработала):
Обращу внимание, что можно было воспользоваться методом автоматического добавления цели «Отправка формы»:
В этом случае событие отправки будет распознано автоматически и после статистики нашей конкретной цели, ниже мы можем наблюдать фиксацию автоматической.
Задача: ограничить возможность заказа пользователя определённой суммой товаров в корзине.
То есть, пока клиент нашего интернет-магазина не добавит товаров на нужную сумму в корзину заказ будет невозможен. Вот так это выглядит в виде уведомления на странице корзины:
Уведомление также будет выводиться и в момент обработки данных непосредственно на страницы заказа и не позволять ему состояться пока условие не будет удовлетворено.
Решение: просто добавьте этот php-сниппет и укажите в виде числового значения минимальную сумму для осуществления заказа:
/**
* Set a minimum order amount for checkout
*/
add_action('woocommerce_checkout_process', 'wc_minimum_order_amount');
add_action('woocommerce_before_cart', 'wc_minimum_order_amount');
function wc_minimum_order_amount()
{
// Установите цифру минимального значения для осуществления заказа
$minimum = 100;
if (WC()->cart->total < $minimum) {
if (is_cart()) {
wc_print_notice(
sprintf('Ваша сумма заказа %s — вы должны дополнить до минимума в %s чтобы оформить заказ.',
wc_price(WC()->cart->total),
wc_price($minimum)
), 'error'
);
} else {
wc_add_notice(
sprintf('Ваша сумма заказа %s — вы должны дополнить до минимума в %s чтобы оформить заказ.',
wc_price(WC()->cart->total),
wc_price($minimum)
), 'error'
);
}
}
}
Не добавляйте произвольный код в файл родительской темы, functions.php поскольку он будет полностью удален при обновлении темы.
Если не вдаваться в долгие разъяснения, о системе кеширования в WordPress, а попытаться объяснить просто и кратко, то своё пояснение я начал бы с того, что есть некий механизм, который способен снять нагрузку с сервера (место где работает сайт) и тем самым ускорить ваш веб-сайт под управлением WordPress.
Механизм этот называется — кеширование. Принцип работы достаточно простой. Кеширование позволяет использовать готовые сформированные данные, а не генерировать их при каждом повторном обращении к страницам сайта.
Кэш страниц (Page cache)
Чтобы понять суть этого вида кэширования, давайте рассмотрим простой пример. Возьмём этот сайт. Предположим Вася попадает на эту страницу. На сервере (на back-end) происходит много скрытых, невидимых глазу посетителя процессов: обработка запроса, формирования заголовков ответа, выборка данных из базы данных, выполнение логики и вычислительных операций PHP и прочее. В итоге формируется страница, которая должна вернуться в браузер Васи в виде HTML для отрисовки. Сервер получил нагрузку выполняя эту подготовку. Через минуту эту же страницу посещает Петя. Что происходит? Снова происходят те же самые процессы: выборка и обработка данных для формирования страницы, чтобы отправить Пете в браузер. А через пару минут эту страницу посещает девочка Катя. Ну вы догадались что произойдёт, да? 🙂
А представьте, что одновременно эту страницу будут посещать в течении нескольких минут ещё пользователей 100-200 и это нормальная ситуация, даже для свежеиспечённых сайтов. Такую нагрузку может вызвать реклама или рассылка, которая приведёт на эту страницу большое количество посетителей.
Мы можем снять нагрузку с сервера путём страничного кеширования. Проиграем снова эту ситуацию, но уже с реализацией страничного кеширования.
Включен полный страничный кэш
На эту страницу заходит Петя. Происходит та же самая магия: подготовка и обработка данных. Страница сформирована и готова байтами лететь в браузер Пети. Сервер, как обычно отправляет страницу, но за одним исключением. Мы сохраняем копию этой сформированной страницы — это и есть кэш.
Далее заходить на эту страницу сайта Вася. Догадались что будет происходить? Да! Сервер отдаст готовый вариант этой страницы и не будет заново её формировать.
Теперь на время жизни этого кэша всем посетителям сайта будет отдаваться сформированный результат и как следствие — это выигрыш в скорости работы сайта, повышение его производительности за счёт короткого отклика (так как страница уже сформирована) и снятие вычислительной нагрузки.
WordPress не наделён этим механизмом «из коробки» (то есть после установки и первого запуска). Реализовать такое кеширование помогут плагины, такие как:
WP Super Cache
W3 Total Cache
WP Rocket (платный)
Объектный кэш в WordPress
Но в этой статье мы будем говорить об объектном кэшировании в WordPress, которое, кстати, так же «из коробки» является непостоянным. Проиграем опять ситуацию. Заходит на страницу сайта Петя, происходит формирование страницы. И объектный кэш это другой уровень кеширования. На уровне страниц пример был рассмотрен выше и если вы были внимательны, то вспомните что при формировании страницы данные берутся из Базы Данных, то есть происходит, если выражаться техническим языком, их SQL запрос. Представим что запрос был сложный и данные запрашивались из БД по разным критериям (параметрам).
Да, в WordPress есть механизм объектного кэширования в рамках сеанса запрошенной страницы. Предположим, функция get_option() вызывается в рамках страницы 10 раз. Если провести аналогию с кэшированием страниц, то после первого вызова она попадёт в объектный кэш и последующие её вызовы будут уже обслуживаться из встроенного объектного кэша WordPress. Вроде всё классно, неправда-ли? Но что произойдёт если на эту страницу зайдет Вася? Функция get_option() снова будет запрашивать данные и в пока Вася находится на странице и не переходит на другие всё будет хорошо и последующие её вызовы будут обслуживаться из кэша.
Вот это и есть непостоянный объектный кэш. Но нам хотелось бы и это уже само напрашивается, чтобы для новых посетителей сайта не происходили одинаковые запросы из БД, а при повторном запросе данные были взяты из памяти, а не заново формировались ( как по аналогии со страницами).
И это реализуемо. Этот механизм называется — постоянный объектный кэш. Единственное, что реализуется он преимущественно за счёт внешних источников хранения, то есть нужно устанавливать на сервер дополнительное программное обеспечение. И сейчас мы рассмотрим один из самых простых примеров реализации постоянного объектного кэша где как раз таки не нужно ничего устанавливать, хотя есть небольшой нюанс.
Может напрашиваться вопрос: можно ли использовать оба кеширования вместе? Да, можно. И даже если ваш сайт постранично жёстко закеширован, всё равно нужно использовать объектный кэш, что бы уменьшить нагрузку с базы данных при работе, например, в админке, при работе в режиме авторизации пользователей, на страницах которые не должны кэшироваться, такие как корзина и страница оформления заказа и наверняка можно найти целый ряд дополнительных случаев оправдывающих постоянный объектный кэш даже в связке с грамотным страничным.
Кейс (реальный случай)
Мы решили организовать на своём сайте постоянный объектный кеш. Виртуальный хостинг не имеет в своём ПО сервис Redis, а следовательно после активации плагина мы не сможем его задействовать, так как наш тарифный план не включает установку дополнительного программного обеспечения.
Docket Кэш — это плагин для реализации постоянного кеша объектов в WordPress, который хранится в виде PHP-кода. Задача плагина предоставить альтернативный вариант для постоянного объектного кэша для тех, кто не может использовать на своих серверах такие сторонние решения, как: Redis или Memcached.
После активации плагина нам становятся доступны его разделы настроек:
Принцип работы плагина отличается от популярных решений, таких как Redis или Memcached, а также Docket Cache не использует механизм сериализации/десериализации объектов PHP для хранения в файлах в виде строк, а сохраняет данные путем преобразования объекта в простой PHP-код, что приводит к более быстрому извлечению данных и повышению производительности при включенном Zend OPcache.
Что такое Zend OPcache?
OPcache — это механизм кэширования, встроенный в PHP, который повышает производительность за счет хранения предварительно скомпилированного байт-кода сценария в общей памяти, тем самым устраняя необходимость PHP загружать и анализировать сценарии при каждом запросе.
Docket Cache преобразует кэш объектов в простой PHP-код. При чтении и записи кеша он будет напрямую использовать OPcache, что приводит к более быстрому извлечению данных и повышению производительности.
У плагина много всяких настроек доступных в разделе Configuration, включите некоторые из них:
В разделе Обзор можно увидеть статистику кеширования — это хороший знак, значит плагин работает 🙂
Есть также отдельный раздел OPcache где мы можем получить техническую информацию, в частности полезно понимать сколько доступно и задействуется памяти для хранения. Ну и сами файлы с кэшем.
Требования
Для использования Docket Cache нужно выполнить минимальные требования:
PHP 7.2.5
WordPress 5.4
Zend OPcache
Естественно все тонкости и настройки рассматривать смысла я не вижу. Главное что бы ваш сервер и его ПО удовлетворял минимальным требованиям и после активации плагина появлялись файлы, статистика кэша. Для начала это уже будет неплохо 🙂
Вот так хранится кэш на сервере. Это директория для хранения.
А вот файлы и их содержимое
Хранятся данные в виде массивов в синтаксисе PHP
Для технических специалистов возможно будет полезна эта ссылка на документация плагина
Подытожим об объектном кешировании
Кэширование объектов — это процесс, который сохраняет результаты запросов к базе данных, чтобы быстро восстановить их в следующий раз, когда они потребуются.
Кэшированный объект будет оперативно обслуживаться из кеша, а не отправлять несколько запросов в базу данных. Это более эффективно и снижает огромную ненужную нагрузку на ваш сервер.
Проще говоря, кэширование объектов позволяет копировать часто используемые объекты и хранить их в более близком месте для более быстрого использования.
За отрисовку кнопки, как элемента HTML, отвечает эта строка:
<button id="go-back">Вернуться назад</button>
Единственное, если быть точными и делать всю реализацию на JavaScript, получается по доброму этот элемент нужно создавать тоже при помощи скрипта. Выглядеть это может примерно так:
А за функционал на стороне клиента вот этот сниппет на JavaScript, который прослушивает событие клика по элементу с идентификатором «go-back» и вызывает на это событие метод back() принадлежащий интерфейсу History, который предписывает браузеру вернуться на одну страницу назад в истории сеанса.
@TODO По доброму ещё можно сделать проверку на существование значения «реффера» и принадлежности к текущему домену.
Мы рассмотрели механизм решения данной задачи на стороне клиента (браузера) при помощи JavaScript. Теперь давайте рассмотрим вариант на стороне сервера, при помощи PHP:
Реализация на PHP
В контексте WordPress, на стороне сервера подобное можно реализовать при помощи функции WP из ядра, которая является обёрткой других функций.
Начинающих пользователей могут смутить открывающие и закрывающие теги PHP, часто в этом допускают синтаксическую ошибку. Ниже привожу пример где я вывел обработку (функцию отчистки) URL из атрибута href, тем самым позволив исключить теги PHP:
// получаем реферальную ссылку
$return_url = wp_get_referer();
// если не false продолжаем ...
if ($return_url) {
// обработка УРЛ (подготовка)
$url = esc_url($return_url);
// вывод
echo"<a class='button' href='{$url}'>Вернуться назад</a>";
}
P.S. тоже «не сахар» вариант 🙂 Будьте внимательнее с кавычками. Чтобы в строке языковой конструкции echo у нас выводилась переменная с нашим УРЛ, необходимо убедиться что сама строка в двойных кавычках, а атрибуты элемента ссылки в одиночных!
Небольшим преимуществом серверного метода можно считать тот факт, что если у клиента будет выключен в браузере JavaScript или возникнут ошибки которые не дадут отработать первому решению (на JS), то наша кнопка всё равно окажется в DOM так как приходит с сервера, а не формируется на стороне клиента.