Для начала обозначим проблему. Мы пишем контент для сайтов, которые работают на самых разных системах управления (CMS). В том числе работаем и с 1с Битрикс. И тут выяснилось, что в битриксе нет встроенного функционала черновиков, как на том же вордпрессе или друпале. Есть возможность просто активировать и деактивировать элемент, но активировать так, чтобы не открывать пока в публичном доступе, а посмотреть, что получается — нет. Типичный функционал для статьи в блог, например. Короче, вот с этим и будем разбираться.
Попробуем поколдовать с правами доступа. У битрикса их настраивать можно гибко, для ограничения того, что и кому можно делать в админке — очень удобно.
Сначала в настройках инфоблока нужно включить "расширенное управление правами". Это позволит настраивать нужные права вплоть до отдельного элемента. Без этой галки установленные права доступа в настройках инфоблока наследуются для всех его разделов и элементов.
Выбираем инфоблок, для которого нам нужен статус черновика, находим этот чекбокс, ставим галку, сохраняем. Теперь у элементов этого инфоблока появится вкладка "Доступ", в которой мы сможем задать нужные права.
Теперь, выбрав нужный элемент (например, статью), в этой вкладке мы можем полностью изменить доступы. В нашем случае, чтобы скрыть статью-черновик от всех подряд, выставляем для группы "все посетители" права "нет доступа", а для нужной нам группы пользователей (например, "контент-менеджеры") выставим права доступа "чтение".
Так статья будет скрыта для обычных посетителей сайта, но будет доступна для чтения всем залогиненным пользователям, состоящим в группе "контент-менеджеры".
Группы пользователей можно отредактировать в настройках: Настройки - Пользователи - Группы пользователей. Уровни доступа тоже настраиваются: Настройки - Пользователи - Уровни доступа.
Это вполне рабочий способ решить поставленную задачу, но у него есть ряд минусов, из-за которых я его решил не использовать:
Из-за озвученных выше причин этот способ я решил не использовать. Давайте попробуем другие.
Это максимально прямолинейный способ, который, как мне кажется, разработчики битрикса воспринимают как подходящий для статуса "черновик". Хочешь показывать элемент — проставь галочку в чекбоксе «Активность». Не хочешь — сними. Раз черновик, значит, не должен отображаться, но в админке посмотреть можно.
Его недостаток как раз в том, что неактивные элементы можно посмотреть только в админке, а проверить, как выглядит верстка элемента — переключившись на режим «визуальный редактор».
Я стараюсь держаться от визуального редактора подальше. Во всех cms, с которыми я сталкивался, переключение на него потом ломало верстку, отступы, вставляло ненужные теги и так далее. Да и нам хочется иметь возможность посмотреть черновик не в админке, а уже в контексте всей верстки сайта глазами клиента, но пока без публикации. А для этого нам нужно иметь возможность отображать неактивные элементы на какой-то странице.
Вероятно, вывести неактивные элементы на сайте можно. Например, через метод GetList, отфильтровав только те элементы, которые неактивны. Можно сделать некий список со ссылками, чтобы можно было посмотреть, как выглядит сверстанный черновик. Но в админке останется просто индикация "активен/неактивен". И в таком статусе не будет понятно, какие элементы должны быть сняты с публикации навсегда, а какие не являются активными временно, потому что на доработке (черновики).
Поэтому этот способ я тоже отверг.
Это способ, который я и выбрал.
Битрикс поддерживает дополнительные свойства для элементов инфоблока «из коробки» (в отличие от того же вордпресса). Свойства - это произвольные поля, где вы можете хранить любые нужные данные в подходящем формате (строка, список, файл и так далее).
Итак, у нас есть простой инфоблок с базовым набором полей (название, анонс, подробнее…), но нам нужно где-то хранить статус черновика в виде «да/нет». Чтобы добавить новое свойство, пойдем в настройки инфоблока (туда же, где мы меняли настройки доступа), выберем вкладку свойства и добавим новое.
Что важно учесть:
В меню настроек нам нужно проверить вот что:
Теперь для элементов этого инфоблока доступно новое поле, в котором мы выбираем, черновик это или нет.
Теперь, когда у нас для каждой статьи массив с данными содержит новое значение в поле "черновик", мы можем скрыть элементы, у которых в этом поле указано "да", для обычных посетителей сайта, а для админов и нужных групп пользователей — оставить.
Напомним, что мы все это затеяли для вывода статей. Для этого мы использовали комплексный компонент news (это самый простой подход), у которого за вывод списка элементов (статей) отвечает компонент news.list, а за вывод отдельного элемента (статьи) — news.detail.
В компоненте news.list, отвечающем за вывод списка элементов, мы хотим скрыть черновики из общего списка для всех пользователей и показывать только админам и контент-менеджерам.
Для этого сначала определим, является ли посетитель залогиненным юзером, и если да, то к какой группе он относится. Мы это проверим в файле result_modifier, чтобы уже в template просто выводить нужную информацию.
if(\Bitrix\Main\Engine\CurrentUser::get()->getId()) { $user_groups = \Bitrix\Main\Engine\CurrentUser::get()->getUserGroups(); if(in_array(1, $user_groups) || in_array(5, $user_groups)) { $arResult['SHOW_DRAFTS'] = true; } else { $arResult['SHOW_DRAFTS'] = false; } }
Нужно чуть пояснить код. 1 и 5 — это id групп пользователей. 1 — админы, 5 — контент-менеджеры. Если пользователь относится к этим группам, передадим в arResult значение, показываем ли черновики (true) или не показываем (false).
В этом же файле получим значение поля "черновик" и запишем его тоже в arResult в чуть более удобном виде, чтобы не перегружать файл шаблона лишней логикой.
foreach ($arResult['ITEMS'] as $itemKey => $arItem) { $draft_prop = CIBlockElement::GetProperty(3, $arItem['ID'], "sort", "asc", array("CODE" => "DRAFT")); while($ar_props = $draft_prop->Fetch()){ if ($ar_props['VALUE_ENUM'] === 'Да') { $arResult['ITEMS'][$itemKey]['DRAFT'] = 'Y'; } else { $arResult['ITEMS'][$itemKey]['DRAFT'] = 'N'; } } }
Чуть поясним код. Перебираем все элементы инфоблока и получаем значение свойства с помощью GetProperty(). Записываем полученные данные в arResult в массивы тех же элементов для последующего использования в файле template.php, отвечающего за рендеринг страницы.
Теперь в шаблоне (файл template.php) мы проверим, можно ли показывать черновики пользователю. Если можно, то переберем элементы и выведем просто ссылки, чтобы контент-менеджеру было проще понять, какие статьи в черновиках. А потом выведем и остальные элементы так, как мы бы вывели их для всех посетителей.
<?php if (!empty($arResult['ITEMS'])): ?> <?php if ($arResult['SHOW_DRAFTS'] === true) : ?> <?php foreach($arResult['ITEMS'] as $arItem):?> <?php if($arItem['DRAFT'] === 'Y') : ?> <p>Черновик: <a href="<?= $arItem['DETAIL_PAGE_URL']?>"><?= $arItem['NAME']?></a></p> <?php endif; ?> <?php endforeach; ?> <?php endif; ?> <div class="row row-cols-1 row-cols-sm-2 row-cols-lg-3 row-cols-xxl-4 g-4 mb-4"> <?php foreach($arResult['ITEMS'] as $arItem): ?> <?php if($arItem['DRAFT'] === 'N') : ?> <article class="col"> <div class="card portfolio-wrapper portfolio-title"> <?php if(!empty($arItem['PREVIEW_PICTURE']['SRC'])) : ?> <img src="<?= $arItem['PREVIEW_PICTURE']['SRC']?>" class="card-img-top"> <?php else : ?> <div class="main-background dummy-title"></div> <?php endif; ?> <div class="card-body"> <h5 class="card-title"><?= $arItem['NAME']?></h5> <p class="card-text"><?= $arItem['PREVIEW_TEXT']?></p> <a class="read-more btn btn-primary" href="<?= $arItem['DETAIL_PAGE_URL']?>">Читать <i class="fa fa-arrow-right"></i></a> </div> </div> </article> <?php endif; ?> <?php endforeach; ?> </div> <?php endif; ?>
Со списком разобрались. Теперь осталось закрыть доступ к самой статье-черновику, если пользователь перейдет по прямой ссылке.
Для этого сначала проверим, какое значение у свойства "черновик". Если значение "да", определим тип пользователя (как мы уже делали в списке) и отправим код 403 (доступ запрещен) тем, кому нельзя смотреть этот материал. Тем, кому можно, покажем и упростим жизнь, добавив к названию капсом ЧЕРНОВИК, чтобы не запутались.
Все это делаем в result_modifier.php для компонента news.detail
if ($arResult['PROPERTIES']['DRAFT']['VALUE'] === 'Да') { if(\Bitrix\Main\Engine\CurrentUser::get()->getId()) { $user_groups = \Bitrix\Main\Engine\CurrentUser::get()->getUserGroups(); if(in_array(1, $user_groups) || in_array(5, $user_groups)) { $arResult['NAME'] = 'ЧЕРНОВИК: '.$arResult['NAME']; } else { header("HTTP/1.1 403"); exit; } } else { header("HTTP/1.1 403"); exit; } }
Так как мы "отбриваем" пользователей, которым нельзя смотреть черновики, еще на этапе подготовки страницы, в самом шаблоне элемента дополнительные проверки не нужны.
Ну вот и все. Теперь у нас битрикс стал чуть больше похож на wordpress =)
Поделиться: