Довольно часто перед разработчиком встает задача реализации SEO тэгов уже на готовом проекте или если не реализации, то как минимум модернизации. Если это сайт-визитка, состоящий из максимум 20 страниц - проблемы не наблюдается, но что делать если это большой интернет-магазин с несколькими тысячами товаров или портал, в основе которого лежат те же товары, но на разных страницах подаются под разным "соусом" (отзывы, статьи, объявления - прикрепленные к товарам или разделам товаров). Тогда управление, модернизация и оптимизация SEO тэгов становится затруднительной, запутанной трудоёмкой или даже невозможной задачей (по причине частой смены политики продвижения сайта).
В этой статье я продемонстрирую некоторые возможности модуля SEO инструменты: Управление метатегами PRO, которые позволяют гибко настраивать и устанавливать мета тэги на любой странице сайта (будь она статическая или динамическая). Несмотря на то, что разработчики уже давно ведут работу над созданием решений генерирующих мета теги. Несмотря на то, что и в Битрикс есть приемы управления мета тегами на динамических разделах(страницах), все это - лишь локальные или ограниченные приемы. Они не решают основной проблемы - конфликта программистов и SEO-специалистов и решения задачи в глобальном ключе.
Поэтому мы пошли другим путем. Сначала совместно с SEO-специалистами мы разработали методику управления мета тегами на проекте. А уж затем на базе многолетнего опыта реализовали инструменты, которые стали основой для нашего модуля. В его основу лёг совершенно иной концепт:
Облегчить жизнь разработчика, убрав из его круга задач работу по установке мета тэгов (или любой их модернизации);
Облегчить жизнь SEO специалисту, добавив в его круг задач полное и гибкое управление тэгами на сайте не прибегая к помощи программиста;
Создать целую (и цельную) систему по работе с SEO тэгами на сайте, а не разовые "подпорки" и "костыли", нуждающиеся в постоянной кастомизации от проекта к проекту или на сайте в целом.
Первичные сведения
Типичный пример реализации задачи по установке SEO данных обычно происходит уже после создания рабочего проекта перед запуском либо после установки и настройки типового решения. Именно на этом примере в данной статье я разберу некоторые принципы простого, но достаточно гибкого управления тэгов по принципу "установил и забыл". Для этого нам понадобится:
Первая приятная плюшка заключается в том, что модуль после установки уже работает и текущие установленные теги на странице можно просмотреть перейдя в режим правки сайта:
Необходимые данные
Настрою модуль для раздела каталога товаров (на сайте /catalog/). На странице каталога товаров расположен комплексный компонент bitrix:catalog. Таким образом исходные данные:
Типовой интернет магазин
Установленный модуль для работы с мета тэгами
Комплексный компонент Битрикс (bitrix:catalog)
Что нужно сделать: - Для групп товаров установить тэги по следующему шаблону:
title: Купить керамическую плитку #GROUP_NAME# от #BRAND# в <вырезано>
description: #GROUP_NAME# от #BRAND# - оптимальное решение для отделочных работ
keywords: купить #GROUP_NAME#, купить #BRAND#, купить #GROUP_NAME# в <вырезано>, купить #BRAND# в <вырезано>
- Для детальной карточки товааров установить тэги по следующему шаблону:
title: Купить #NAME# в <вырезано>| #ELEMENT_GROUP_NAME# | #ELEMENT_BRAND#
description: #KGKP##NAME# от производителя #ELEMENT_BRAND#. Толщина керамической плитки - #TOLSHCHINA#. #KGKP# цвета #TSVET# c поверхностью #POVERKHNOST# и рисунком типа #RISUNOK# за счет оптимального размера #RAZMER# идеально подходит для укладки на #NAZNACHENIE#.
keywords: купить #NAME#, купить #KGKP##NAME#
- Должна быть возможность установки ключей из заполненных свойств товара (свойства элемента инфоблока).
Таким образом исходя из условий задачу можно разделить на несколько частей:
Создание ключей и установка их значений (ключ - сущность вида #<название ключа>#) на необходимых страницах. Например создать ключ NAME и его значение установить в Декор Edem 20x25 (ED2B451);
Установить тэги в соответствии с заданными шаблонами с установленным набором значений ключей.
Было бы очень хорошо, чтобы пользователь сам создавал и редактировал шаблоны, с течением времени они меняются..Для этого в модуле реализован механизм правил (основанный на инфоблоках), о котором речь пойдет ниже.
Установка ключей для раздела
Итак, что означают заданные в задании ключи:
GROUP_NAME - это текущий раздел товаров, в котором мы находимся.
BRAND - это раздел товаров первого уровня
Устанавливать ключи можно тремя известными мне способами:
в файле component_epilog.php простых компонентов (если компонент находится в пространстве имен bitrix, так как он не попадает в кэш);
где угодно в шаблоне простых компонентов или на страницах комплексного компонента (если кэш отключен на сайте или у компонента)
непосредственно в кастомизированном компоненте, помещенным в свое пространство имен (тогда вы лишаетесь поддержки обновления компонента).
Последние два способа это "экзотика", которая влечет свои головные боли, ее в этой статье я не буду касаться, поэтому остановимся на первом: Для установки ключей я буду использовать шаблон компонента bitrix:catalog.section.list комплексного компонента bitrix:catalog , так как я работаю только с секциями и часть необходимых данных уже доступна в шаблоне компонента. Данные о текущем разделе доступны в шаблоне компонента в ячейке массива $arResult["SECTION"]. А раздел первого уровня можно вытащить используя метод CIBlockSection::GetNavChain. Вынесем данные из кэша, как описано здесь. Все манипуляции проведу в файле result_modifier.php.
Чтобы посмотреть какие ключи установлены на данной странице нужно включить режим правки:
Создание правил для разделов
Перед тем как создать правила, думаю пару слов просто необходимо сказать об условиях их выборки для установки тегов, а условия простые:
ВСЕ ключи заданные в свойствах элемента инфоблока "Правила (для тэгов)" установлены на странице. То есть все ключи в свойстве элемента Все ключи (служебное) заданы.
Таргетинг (поля инфоблока Где показывать и Где не показывать).
В случае если в выборку под выполненные выше условия попадают больше двух элементов, выбирается тот, который имеет меньшую сортировку (поле SORT)
Теперь необходимо создать правила, для установки мета тэгов на странице. Для этого необходимо создать элемент в инфоблоке "Правила тегов" (устанавливается с модулем).
Создаю правило для разделов 1 уровня:
В шаблонах для мета тэгов указываю только один ключ GROUP_NAME (как видно из картинки), устанавливаю шаблоны для тегов и таргетинг.
Создаю второе правило для разделов 2 уровня и выше:
В шаблонах для мета тэгов указываю ключи GROUP_NAME и BRAND (как видно из картинки), устанавливаю шаблоны для тегов и таргетинг.
Чтобы просмотреть какое правило приминилось достаточно зайти в режим правке на необходимой странице и получить исчерпывающую информацию:
Установка ключей для детальной карточки
Итак, что означают заданные в задании ключи:
NAME- Наименование товара;
ELEMENT_BRAND - это раздел товаров первого уровня;
ELEMENT_GROUP_NAME - это текущий раздел-родитель товара;
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
if(CModule::IncludeModule("alexkova.megametatags")){
$arKeys = array();
foreach($arResult['META_KEYS'] as $key=>$nameKey){
$arKeys[] = array("KEY"=>$key,"VALUE"=>$nameKey,"WHERE_SET"=>$this);
}
if ($arKeys){
CMegaMetaKeys::setKeys($arKeys);
}
}
?>
Просмотреть установленные ключи можно на странице в режиме правки:
Создание правила для детальной карточки
Теперь необходимо создать правила, для установки мета тэгов на странице. Для этого необходимо создать элемент в инфоблоке "Правила тегов" (устанавливается с модулем).
Создаю правило для детальной карточки:
В данном случае SEO специалист, опираясь на условия выборки необходимого правила может создавать различное количество правил для детальной карточки с различным набором ключей (в нашем случае в качестве ключей используются мнемонические коды свойств инфоблока).
Вот в принципе и всё, прорезюмируем: для того чтобы устанавливать теги нужно:
Установить ключи на странице (в любом месте) для шаблонов необходимых тэгов;
Создать правила, из которых будут браться шаблоны для тэгов.
Данный пост можно использовать как инструкцию по настройке и интеграции модуля SEO инструменты: Управление метатегами PRO с бесплатным типовым решением от Битрикса Современный интернет магазин.
Не найду материалов по установке ключей модуля, чтобы генерировались....печатные и видео материалы не дают алгоритма правильных действий чтобы заработало
Начать хочется, с казалось бы, элементарной вещи – концепции разделения представления логики того или иного скрипта(компонента) и его представления. Битрикс представляет возможность работать с шаблонами компонентов, не трогая их логичесую реализацию, и более того дает возможность «допилить» ее путем создания некоторых файлов типа «result_modifier.php». Казалось бы все элементарно, и большинство разработчиков пользуется этой замечательной вещью в отношении HTML и PHP. Бывают конечно исключения и в практике приходится встречать вызовы одного компонента в шаблоне другого, а в шаблоне второго вызов еще одного, а в шаблоне третьего еще двух компонентов, в шаблоне которых вызывается пятый но с разными входными параметрами (Типовое решение «Медицинских учреждений»). Согласитесь, если это не комплексный компонент, то работать с таким кодом, и дорабатывать его очень трудно и тяжело. Ситуация с JavaScript не настолько катастрофична, как в предыдущем примере, но на мой взгляд если уж разделять логику и представление – то быть последовательным до конца и включить в эту концепцию JavaScript в том числе.
От человеческой лени или незнания или каких-либо других причин приходится сталкиваться со следующим мнением «Я так всегда делал», «Это надежно», «Так делали мои деды и прадеды». В пору вспоминается анекдот: «В комнате муха долбиться в окно, желая вылететь наружу. С другой стороны к ней подлетает другая муха и говорит: «Ты чего долбишься? Вон же форточка открыта». На что первая ей отвечает: «Нет, мой отец бился, мой дед бился, мой прадед бился в это окно и я биться буду.».». Есть несколько причин не делать так, как ты делал когда-то, и в этой статье я постараюсь осветить некоторые из них.
Атрибуты oncklick, onchange, onmouseover и им подобные в HTML Часто в чужом коде приходится встречаться с таким примером:
Обратим внимание на атрибут onclick. Вариантов содержимого может быть несколько. Возможен какой-то код после которого стоит return false, возможен вызов функции, которая всегда возвращает ложь:
1. Концепция разделения программирования и представление информации. Битрикс дает замечательную возможность перенести весь свой код в файл script.js, который автоматом подключается и очень удбен для разработки. Мое мнение - HTML должен быть чистый, со вкраплениями PHP и если возможности самого языка JavaScript а тем более популярного Framework jQuery позволяют не добавлять в HTML ничего не нужного, то этим стоит пользоваться. Сегодня мы сделали так, через месяц по другому, еще через неделю пришлось изменить логику и что то уже не приходит, какие то данные изменились и надо везде править изменения. 2. Происходит элементарное затирание объекта MouseEvent, который передается всегда в любом событии. Таким образом передавая параметры в нашу фукцию getData(this,<?=id?> мы просто лишаем себя многих возможностей, в том числе тмены стандартного обработчика события, но о нем еще поговорим ниже. Вот пример, который показывает объект MouseEvent, который содержит всю информацию о нажатии, и поверьте там есть все и даже больше того чего нужно:
JavaScript
<a href="/catalog/sect_1/file.php" class="product_<?=$ID?>" id="id_product" onc lick="return false;">Перейти</a>
<sc ript type="text/javascript">
function getData(event){
console.log(event);
}
var a = docu ment.getElementById('id_product');
a.addEventListener('click',getData);
</script>
Таким образом, если мы передадим любой параметр в фукцию, то затрем параметр по умолчанию, что не есть хорошо. Этого можно избежать если все свои данные, необходимые для обработки, вы передадите в атрибут класса, или добавите элементы в DOM документ которые будут содержать эти данные опять же в своих классах. Если вы используете HTML 5, то для этого теперь есть атрибут data-{название}=”значение”, при небольшом ухищрении этот тег будет работать и в старых IE. Вариантов передать данные в HTML масса. В последствии многие просто не хотят или ленятся эти данные получать и вытаскивать из структуры DOM. Что тоже никак не оправдывает такой подход. С одной стороны использование атрибутов событий в HTML дает нам небольшое преимущество в скорости и простоте, но это старый век, и так делать некрасиво, тем более что зачастую, сами того не подозревая, нам нужны возможности объекта MouseEvent.
3. О «return false». Вообще в парадигме программирования функция возвращает либо результат операций, либо результат того что операции были выполнены успешно, либо результат того, что они были выполнены с ошибками или вовсе не выполнены. Уж точно возвращение лжи не было придумано для того чтобы ссылка не отрабатывала по событию click. Тем более часто бывает нужно что-то вернуть из функции, а мы уже себе поставили ограничение, и наша функция должна возвращает только ложь, чтобы не сработал стандартный обработчик тега <a>. Некоторые идут дальше и не используют атрибут href (что не верно, так как при сбое в скриптах или отключенной поддержке скриптов пользователь никуда не попадет), либо затирают или удаляют атрибут href в самом скрипте, что тоже является не красивым и приводит к той же проблеме сбоя скрипта и пользователь никуда не попадет. Вернемся к нашему объекту MouseEvent. А ведь в нем уже все есть. Для JavaScript не нужно ничего дописывать, так как вышеприведенных примерах мы и так переопределили обработчик события click. А вот для jQuery это делается следующим образом:
Что здесь происходит? Во первых метод each() – нужен совсем для других целей, он необходим для обработки массива объектов jQuery в данном случае его применение губительно. Фактически мы для кажого тега <a> назначили отдельное событие, то есть у нас зарегестрировано 4 события onclick, которые делают одну и ту же вещь! Если у вас на странице информация не добавляется с помощью ajax, то необходимо использовать метод bind() который зарегестрирует одно событие для данной группы тегов:
Если же информация на страницу подгружается технологией ajax, то используя метод bind() новые тэги или группы тегов не будут откликаться по вашему обработчику, для этого используется метод live():
Теперь все элементы структуры DOM в том числе и вновь добавленные будут закреплены за данным обработчиком события. Примечание: Будте аккуратны используя данные методы. В сарых IE они не работают при использовании jQuery версии ниже 1.4.2. Самый надежный метод регестрирования события on() так как он не меняется в jQuery от версии к версии и на его основе создаются другие методы, он является как бы родителем:
Часто я сталкиваюсь с высказываниями «Нужно чтобы все работало быстро, минимум запросов, оптимальное использование PHP». И часто вижу на сайтах, что сервер быстро сгенерировал страницы, выполнил запросы, а страница все еще не готова, потому что грузятся скрипты. По хорошему нужно было бы написать целый раздел на эту тему, а не подтему одной статьи, но когда я вижу следующий код, то понимаю, что человек не совсем понимает для чего он использует jQuery:
При загрузке страницы jQuery находит все теги с классом «links». Далее ко всем этим ссылкам добаляется параметр ajax. Создается впечатление что пользователь нажмет на все эти ссылки разом. Пользователь всегда нажмет на одну ссылку, поэтому целесообразний использовать следующий код:
Таким образом мы поменяем ссылку только тогда, когда это нужно а не все время и на каждой странице(если скрипт не попадет в кэш). Возможен вариант когда пользователь не будет нажимать эти ссылки вообще, тогда зачем их обрабатывать? Бывает так, что в теле функции происходит много ненужных опреаций. N раз берется элемент документа:
jQuery
<sc ript type="text/javascript">
$('.links').each(f unction(){
var a = $(this).attr('class')+'_show';
var b= $('.someClass').attr('class');
});
</script>
В переменную а всё кладется как положено, но в переменню b каждую итерацию кладутся одни и те же данные, но с огромными потерями производительности, то есть на каждый чих мы ищем в структуре документа теги с классом someClass. Имя возможность их сохранить мы все равно дергаем DOM (а если количество строк в документе 5000?). Необходимо выносить такие вещи из тела функции:
jQuery
<sc ript type="text/javascript">
$(docu ment).ready(f unction(){
var b= $('.someClass').attr('class');
$('.links').each(f unction(){
var a = $(this).attr('class')+'_show';
});
});
</script>
или:
jQuery
<sc ript type="text/javascript">
(f unction(){
var b= $('.someClass').attr('class');
$('.links').each(f unction(){
var a = $(this).attr('class')+'_show';
});
})();
</script>
Первый вариант отработает по загрузке и готовности структуры документа, второй вариант - функция будет вызвана сразу же как только она встретится. К сожалению второй вариант и возможность битрикса с подключением файла script.js не совместим, так как этот файл подключается методом AddHeadScript(), а это значит, что она будет вызвана в head, до построения дерева. Второй вариант предпочтителено размещать в конце документа.
Эпилог
На этом все. В данной статье я старался рассмотреть лишь возможность делать лучше, и это лишь мое мнение. Я так же не отрицаю вариантов, когда нужно использовать другие подходы, гланое чтобы их использование было аргумментированным и целесообразным. Часто я встречаю непонятный код в компонентах Битрикс, которых сами разработчики уходят от использования своего стандартного функционала, вохможно это как раз тот пример, когда лучше сделать по другому.
Согласен с документ реди, но в пределах компонента, возможно структурно вынести и разложить по полочкам:) Просто когда видишь половину скрипта в шаблоне половину в файле скрипта, другая половина в структуре сайта попробовать найти что-то тяжело. Хотя это вопрос скорее стиля чем использования onclick или нет
О «return false». Вообще в парадигме программирования функция возвращает либо результат операций, либо результат того что операции были выполнены успешно, либо результат того, что они были выполнены с ошибками или вовсе не выполнены. Уж точно возвращение лжи не было придумано для того чтобы ссылка не отрабатывала по событию click.
только не в javascript) Почему бы везде, где ничего не возвращается, не дописывать "return true", например? "возвращение лжи для того чтобы ссылка не отрабатывала по событию click" - разве не есть частный случай того, для чего была придумана конструкция return?
Семеритов Александр написал: только не в javascript) Почему бы везде, где ничего не возвращается, не дописывать "return true", например? "возвращение лжи для того чтобы ссылка не отрабатывала по событию click" - разве не есть частный случай того, для чего была придумана конструкция return?
Хорошей практикой кода является что-то возвращать. В JavaScript обычно возвращают указатель на объект, чтобы можно было делать вот так:
Вот вы все спорите, а зря Вставлю свои 5 копеек на базе N лет управления проектами, плюс N лет разработки сайтов
Когда SEO спланировано на этапе разработки, причем с точностью до болтика и гайки - все гуд, на выходе вы получите комфортную "машинку"
Но, поверьте, когда на выходящий с конвеера автомобиль нападает толпа "стервятников-тюнингаторов", то уже не важно кто они по специальности, SEO или CEO.
Пример правильно решенной задачи: У меня был опыт, когда я лично (сам когда то SEO занимался), рекомендовал заказчику сделать один раздел хитрым образом. Кое-как переборол сопротивление и протолкнул свой вариант уже на уровне "не заставляйте меня объяснять, просто доверьтесь". Результат: данный раздел уже четвертый год подряд возглавляет топы по одному из коммерческих запросов. Никаких доп. затрат.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».