битрикс https://ctr99.ru/ ru Статус страницы «черновик» в 1с битрикс (3 способа) https://ctr99.ru/articles/status-stranitsy-chernovik-v-1s-bitriks-3-sposoba <span>Статус страницы «черновик» в 1с битрикс (3 способа)</span> <span><span>Гость (не проверено)</span></span> <span><time datetime="2023-09-30T11:44:33+03:00" title="суббота, 30 сентября 2023 - 11:44">сб, 30 Сен. 2023 - 11:44</time> </span> <div><p>Для начала обозначим проблему. Мы пишем контент для сайтов, которые работают на самых разных системах управления (CMS). В том числе работаем и с 1с Битрикс. И тут выяснилось, что в битриксе нет встроенного функционала черновиков, как на том же вордпрессе или друпале. Есть возможность просто активировать и деактивировать элемент, но активировать так, чтобы не открывать пока в публичном доступе, а посмотреть, что получается — нет. Типичный функционал для статьи в блог, например. Короче, вот с этим и будем разбираться.</p> <section> <h2>Способ 1 — через права доступа</h2> <p>Попробуем поколдовать с правами доступа. У битрикса их настраивать можно гибко, для ограничения того, что и кому можно делать в админке — очень удобно.</p> <p>Сначала в настройках инфоблока нужно включить "расширенное управление правами". Это позволит настраивать нужные права вплоть до отдельного элемента. Без этой галки установленные права доступа в настройках инфоблока наследуются для всех его разделов и элементов.</p> <section class="wide"> <img src="https://ctr99.ru/sites/default/files/content-assets/medialibrary/065/065d2f00a876f616fbeec885a0567ea5.png" class="img-fluid" alt="настройка расширенных прав доступа для инфоблока"> </section> <p>Выбираем инфоблок, для которого нам нужен статус черновика, находим этот чекбокс, ставим галку, сохраняем. Теперь у элементов этого инфоблока появится вкладка "Доступ", в которой мы сможем задать нужные права.</p> <p>Теперь, выбрав нужный элемент (например, статью), в этой вкладке мы можем полностью изменить доступы. В нашем случае, чтобы скрыть статью-черновик от всех подряд, выставляем для группы "все посетители" права "нет доступа", а для нужной нам группы пользователей (например, "контент-менеджеры") выставим права доступа "чтение".</p> <section class="wide"> <img src="https://ctr99.ru/sites/default/files/content-assets/medialibrary/0c1/0c112c8077feb1d1f364b7a95b1a93c0.png" class="img-fluid" alt="вкладка доступ у элемента при расширенном режиме прав доступа"> </section> <p>Так статья будет скрыта для обычных посетителей сайта, но будет доступна для чтения всем залогиненным пользователям, состоящим в группе "контент-менеджеры".</p> <p>Группы пользователей можно отредактировать в настройках: <span class="fw-bold">Настройки - Пользователи - Группы пользователей</span>. Уровни доступа тоже настраиваются: <span class="fw-bold">Настройки - Пользователи - Уровни доступа</span>.</p> <p>Это вполне рабочий способ решить поставленную задачу, но у него есть ряд минусов, из-за которых я его решил не использовать:</p> <ol> <li>Заходить во вкладку "доступ" и выставлять нужный уровень доступа для каждого элемента (статьи) — неудобно.</li> <li>Мне не удалось быстро придумать, как удобно отслеживать элементы с измененным доступом, например, сформировать список всех статей-черновиков на какой-то странице.</li> </ol> <p>Из-за озвученных выше причин этот способ я решил не использовать. Давайте попробуем другие.</p> </section> <section> <h2>Способ 2 — через статус «активность»</h2> <p>Это максимально прямолинейный способ, который, как мне кажется, разработчики битрикса воспринимают как подходящий для статуса "черновик". Хочешь показывать элемент — проставь галочку в чекбоксе «Активность». Не хочешь — сними. Раз черновик, значит, не должен отображаться, но в админке посмотреть можно.</p> <section class="wide"> <img src="https://ctr99.ru/sites/default/files/content-assets/medialibrary/c4c/c4c28d58afa8ad2d9dccc8803a12c3ea.png" class="img-fluid" alt="чекбокс активность в админке битрикса"> </section> <p>Его недостаток как раз в том, что неактивные элементы можно посмотреть только в админке, а проверить, как выглядит верстка элемента — переключившись на режим «визуальный редактор».</p> <p>Я стараюсь держаться от визуального редактора подальше. Во всех cms, с которыми я сталкивался, переключение на него потом ломало верстку, отступы, вставляло ненужные теги и так далее. Да и нам хочется иметь возможность посмотреть черновик не в админке, а уже в контексте всей верстки сайта глазами клиента, но пока без публикации. А для этого нам нужно иметь возможность отображать неактивные элементы на какой-то странице.</p> <p>Вероятно, вывести неактивные элементы на сайте можно. Например, через метод <a href="https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getlist.php">GetList</a>, отфильтровав только те элементы, которые неактивны. Можно сделать некий список со ссылками, чтобы можно было посмотреть, как выглядит сверстанный черновик. Но в админке останется просто индикация "активен/неактивен". И в таком статусе не будет понятно, какие элементы должны быть сняты с публикации навсегда, а какие не являются активными временно, потому что на доработке (черновики).</p> <p>Поэтому этот способ я тоже отверг.</p> </section> <section> <h2>Способ 3 — через дополнительное свойство</h2> <p>Это способ, который я и выбрал.</p> <p>Битрикс поддерживает дополнительные свойства для элементов инфоблока «из коробки» (в отличие от того же вордпресса). Свойства - это произвольные поля, где вы можете хранить любые нужные данные в подходящем формате (строка, список, файл и так далее).</p> <p>Итак, у нас есть простой инфоблок с базовым набором полей (название, анонс, подробнее…), но нам нужно где-то хранить статус черновика в виде «да/нет». Чтобы добавить новое свойство, пойдем в настройки инфоблока (туда же, где мы меняли настройки доступа), выберем вкладку свойства и добавим новое. </p> <section class="wide"> <div class="row"> <div class="col-md-3 caption"> <p>Что важно учесть:</p> <ol> <li>Для дополнительных свойств битрикс не предлагает тип «чекбокс», где были бы значения только «да/нет», поэтому мы воспользуемся типом "список", в который добавим наши значения.</li> <li>Сортировка нужна, чтобы свойство было на нужном месте в админке. А по символьному коду вы найдете значение этого свойства потом в arResult, когда будете писать логику для вывода черновиков.</li> <li>У каждого свойства есть набор настроек. Чтобы их изменить, кликните на кнопку с тремя точками рядом с чекбоксом «удалить»</li> </ol> </div> <div class="col-md-9"> <img src="https://ctr99.ru/sites/default/files/content-assets/medialibrary/9ea/9ea93aa5de5e141fc623ef3960a71aff.png" class="img-fluid" alt="вкладка свойства в настройках инфоблока"> </div> </div> </section> <section class="wide"> <div class="row"> <div class="col-md-3 caption"> <p>В меню настроек нам нужно проверить вот что:</p> <ol> <li>Чтобы свойство было активно. Но эта галка проставляется автоматически при создании.</li> <li>Чтобы стояла галка рядом с "Показывать на странице редактирования элемента". Тогда это поле появится при добавлении или изменении элемента инфоблока.</li> <li>Чтобы в списке были нужные значения. Нам нужны просто "да" и "нет". XML_ID заполнять не нужно, он заполнится автоматически.</li> </ol> </div> <div class="col-md-9"> <img src="https://ctr99.ru/sites/default/files/content-assets/medialibrary/c19/c1971a74436ebc43dc4bfb86cbb22ea9.png" class="img-fluid" alt="меню настроек свойства ифоблока"> </div> </div> </section> <p>Теперь для элементов этого инфоблока доступно новое поле, в котором мы выбираем, черновик это или нет.</p> <section class="wide"> <img src="https://ctr99.ru/sites/default/files/content-assets/medialibrary/9fe/9fe1efb7e77cbb777fafed90ca7a4f98.png" class="img-fluid" alt="добавленное нами новое свойство черновик в списке полей элемента"> </section> <p>Теперь, когда у нас для каждой статьи массив с данными содержит новое значение в поле "черновик", мы можем скрыть элементы, у которых в этом поле указано "да", для обычных посетителей сайта, а для админов и нужных групп пользователей — оставить.</p> <p>Напомним, что мы все это затеяли для вывода статей. Для этого мы использовали комплексный компонент news (это самый простой подход), у которого за вывод списка элементов (статей) отвечает компонент news.list, а за вывод отдельного элемента (статьи) — news.detail.</p> <p>В компоненте news.list, отвечающем за вывод списка элементов, мы хотим скрыть черновики из общего списка для всех пользователей и показывать только админам и контент-менеджерам.</p> <p>Для этого сначала определим, является ли посетитель залогиненным юзером, и если да, то к какой группе он относится. Мы это проверим в файле result_modifier, чтобы уже в template просто выводить нужную информацию.</p> <div class="fw-bold">/local/templates/main/components/bitrix/news.list/articles_list/result_modifier.php</div> <pre> <code> if(\Bitrix\Main\Engine\CurrentUser::get()-&gt;getId()) { $user_groups = \Bitrix\Main\Engine\CurrentUser::get()-&gt;getUserGroups(); if(in_array(1, $user_groups) || in_array(5, $user_groups)) { $arResult['SHOW_DRAFTS'] = true; } else { $arResult['SHOW_DRAFTS'] = false; } } </code> </pre> <p>Нужно чуть пояснить код. 1 и 5 — это id групп пользователей. 1 — админы, 5 — контент-менеджеры. Если пользователь относится к этим группам, передадим в arResult значение, показываем ли черновики (true) или не показываем (false).</p> <p>В этом же файле получим значение поля "черновик" и запишем его тоже в arResult в чуть более удобном виде, чтобы не перегружать файл шаблона лишней логикой.</p> <div class="fw-bold">/local/templates/main/components/bitrix/news.list/articles_list/result_modifier.php</div> <pre> <code> foreach ($arResult['ITEMS'] as $itemKey =&gt; $arItem) { $draft_prop = CIBlockElement::GetProperty(3, $arItem['ID'], "sort", "asc", array("CODE" =&gt; "DRAFT")); while($ar_props = $draft_prop-&gt;Fetch()){ if ($ar_props['VALUE_ENUM'] === 'Да') { $arResult['ITEMS'][$itemKey]['DRAFT'] = 'Y'; } else { $arResult['ITEMS'][$itemKey]['DRAFT'] = 'N'; } } } </code> </pre> <p>Чуть поясним код. Перебираем все элементы инфоблока и получаем значение свойства с помощью <a href="https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getproperty.php">GetProperty()</a>. Записываем полученные данные в arResult в массивы тех же элементов для последующего использования в файле template.php, отвечающего за рендеринг страницы.</p> <p>Теперь в шаблоне (файл template.php) мы проверим, можно ли показывать черновики пользователю. Если можно, то переберем элементы и выведем просто ссылки, чтобы контент-менеджеру было проще понять, какие статьи в черновиках. А потом выведем и остальные элементы так, как мы бы вывели их для всех посетителей.</p> <div class="fw-bold">/local/templates/main/components/bitrix/news.list/articles_list/template.php</div> <pre> <code> &lt;?php if (!empty($arResult['ITEMS'])): ?&gt; &lt;?php if ($arResult['SHOW_DRAFTS'] === true) : ?&gt; &lt;?php foreach($arResult['ITEMS'] as $arItem):?&gt; &lt;?php if($arItem['DRAFT'] === 'Y') : ?&gt; &lt;p&gt;Черновик: &lt;a href="&lt;?= $arItem['DETAIL_PAGE_URL']?&gt;"&gt;&lt;?= $arItem['NAME']?&gt;&lt;/a&gt;&lt;/p&gt; &lt;?php endif; ?&gt; &lt;?php endforeach; ?&gt; &lt;?php endif; ?&gt; &lt;div class="row row-cols-1 row-cols-sm-2 row-cols-lg-3 row-cols-xxl-4 g-4 mb-4"&gt; &lt;?php foreach($arResult['ITEMS'] as $arItem): ?&gt; &lt;?php if($arItem['DRAFT'] === 'N') : ?&gt; &lt;article class="col"&gt; &lt;div class="card portfolio-wrapper portfolio-title"&gt; &lt;?php if(!empty($arItem['PREVIEW_PICTURE']['SRC'])) : ?&gt; &lt;img src="&lt;?= $arItem['PREVIEW_PICTURE']['SRC']?&gt;" class="card-img-top"&gt; &lt;?php else : ?&gt; &lt;div class="main-background dummy-title"&gt;&lt;/div&gt; &lt;?php endif; ?&gt; &lt;div class="card-body"&gt; &lt;h5 class="card-title"&gt;&lt;?= $arItem['NAME']?&gt;&lt;/h5&gt; &lt;p class="card-text"&gt;&lt;?= $arItem['PREVIEW_TEXT']?&gt;&lt;/p&gt; &lt;a class="read-more btn btn-primary" href="&lt;?= $arItem['DETAIL_PAGE_URL']?&gt;"&gt;Читать &lt;i class="fa fa-arrow-right"&gt;&lt;/i&gt;&lt;/a&gt; &lt;/div&gt; &lt;/div&gt; &lt;/article&gt; &lt;?php endif; ?&gt; &lt;?php endforeach; ?&gt; &lt;/div&gt; &lt;?php endif; ?&gt; </code></pre><section class="wide"> <div class="row"> <div class="col-md-6"> <div class="fw-bold">Так у тех, кто должен видеть черновики в общем списке.</div> <img src="https://ctr99.ru/sites/default/files/content-assets/medialibrary/6f8/6f86e65cae55ec64a8cda35be0d3db6d.png" class="img-fluid" alt="простой список черновиков, который виден только нужным пользователям"> </div> <div class="col-md-6"> <div class="fw-bold">А так у всех остальных.</div> <img src="https://ctr99.ru/sites/default/files/content-assets/medialibrary/aaa/aaade370b835a48b617bf90f4f593fcf.png" class="img-fluid" alt="так выглядит список статей для всех пользователей"> </div> </div> </section> <p>Со списком разобрались. Теперь осталось закрыть доступ к самой статье-черновику, если пользователь перейдет по прямой ссылке.</p> <p>Для этого сначала проверим, какое значение у свойства "черновик". Если значение "да", определим тип пользователя (как мы уже делали в списке) и отправим код 403 (доступ запрещен) тем, кому нельзя смотреть этот материал. Тем, кому можно, покажем и упростим жизнь, добавив к названию капсом ЧЕРНОВИК, чтобы не запутались.</p> <p>Все это делаем в result_modifier.php для компонента news.detail</p> <div class="fw-bold">/local/templates/main/components/bitrix/news.detail/article_single/result_modifier.php</div> <pre><code> if ($arResult['PROPERTIES']['DRAFT']['VALUE'] === 'Да') { if(\Bitrix\Main\Engine\CurrentUser::get()-&gt;getId()) { $user_groups = \Bitrix\Main\Engine\CurrentUser::get()-&gt;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; } } </code> </pre> <p>Так как мы "отбриваем" пользователей, которым нельзя смотреть черновики, еще на этапе подготовки страницы, в самом шаблоне элемента дополнительные проверки не нужны.</p> <p>Ну вот и все. Теперь у нас битрикс стал чуть больше похож на wordpress =)</p> <div class="commercial-service-block"> <img src="https://ctr99.ru/themes/custom/ctr99/assets/img/service-placeholder.jpg" class="commercial-service-block-img item" alt="Разработка сайта на 1С-Битрикс"> <h4 class="item">Разработка сайта на 1С-Битрикс</h4> <div class="commercial-service-block-text item">Настроим ваш проект – от базовых функций до гибкой работы с черновиками и ролями!</div> <a class="commercial-service-block-link item" href="https://ctr99.ru/services/razrabotka-sayta-na-1s-bitriks"> Подробнее об услуге <svg width="12" height="12" viewBox="0 0 12 12" fill="#00A849"> <path fill-rule="evenodd" clip-rule="evenodd" d="M12 0.5C12 0.367 11.948 0.24 11.854 0.146C11.76 0.053 11.633 0 11.5 0H5.5C5.368 0 5.24 0.053 5.147 0.146C5.053 0.24 5 0.367 5 0.5C5 0.633 5.053 0.76 5.147 0.854C5.24 0.947 5.368 1 5.5 1H10.293L0.146 11.146C0.053 11.24 0 11.367 0 11.5C0 11.633 0.053 11.76 0.146 11.854C0.24 11.947 0.368 12 0.5 12C0.633 12 0.76 11.947 0.854 11.854L11 1.707V6.5C11 6.633 11.053 6.76 11.147 6.854C11.24 6.947 11.368 7 11.5 7C11.633 7 11.76 6.947 11.854 6.854C11.948 6.76 12 6.633 12 6.5V0.5Z" /> </svg> </a> </div> </section></div> <div class="article-discussion__field"> <div class="article-comment-form"> <h3>Оставить комментарий</h3> <p class="article-comment-form__note">Комментарии появляются после проверки.</p> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=363&amp;2=comment&amp;3=comment" token="_mSX5djBOxgFt4Kt_PLaKpfIW4MbNzpNArtW1x4vGD4"></drupal-render-placeholder> </div> </div> Sat, 30 Sep 2023 08:44:33 +0000 Гость 363 at https://ctr99.ru https://ctr99.ru/articles/status-stranitsy-chernovik-v-1s-bitriks-3-sposoba#comments