Матвей Земсков

Заметки веб-мастера

Немного о веб-технологиях

Мой блог содержит заметки о различных веб-технологиях, как клиентских, так и серверных. Здесь будут раскрыты вопросы html-верстки, программирования на javaScript и jQuery,разработки на PHP. Не останутся без внимания популярные системы управления сайтом «1С-Битрикс», Joomla и другие. О работе с ними, я также буду писать.

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

В своем блоге я собираюсь публиковать статьи о современных веб-технологиях (HTML5, CSS3 и других). Если в процессе работы над проектами я открываю для себя «свежее» решение какой-либо задачи, я записываю сюда информацию об этом, что позволяет мне при необходимости применять полученные знания в будущем.

Надеюсь информация будет полезна для посетителей.

 
Понедельник, 22 августа 2016 12:54

Перенос информации со статических страниц в инфоблок

Оцените материал
(1 Голосовать)

Предположим, на вашем сайте имеются страницы, на которых размещен список однородных элементов. Например, список часто задаваемых вопросов и ответов на них (FAQ). Причем страницы эти статические: «вопросы-ответы» на них не выводятся каким-либо компонентом системы, а были размещены в виде обычных HTML-таблиц. Согласитесь, что это неверный подход, потому что такая информация должна храниться в каком-либо информационном блоке.

В этой статье я расскажу как исправить эту ситуацию и поместить эти данные в информационный блок.

Основными инструментами, которыми мы будем пользоваться при решении этой задачи будут JavaScript (jQuery) и PHP (Bitrix Framework).

Как обычно, все действия по решению задачи будут проводиться в демо-версии системы «1С-Битрикс» (редакция «Стандарт»), которую вы можете бесплатно скачать с официального сайта. (). При установке CMS на локальный веб-сервер, выберите «Версию для разработчиков».

После установки CMS «1С-Битрикс» в ней уже будет доступен инфоблок с идентификатором 13 и именем “FAQ” для хранения часто задаваемых вопросов. В него мы и будем добавлять данные. Правда, нам необходимо будет совершить в нем некоторые настройки, а именно: добавить свойства и создать секцию, но об этом немного позже.

Давайте я сначала вкратце опишу как всё это будет работать, а затем рассмотрим каждый момент более подробно.

Каждую страницу мы будем обрабатывать отдельно, поэтому на данный момент важно ознакомиться с ее структурой.

Обращаю внимание, что структура страницы является ключевым моментом при решении этой задачи. Все скрипты пишутся под нее. В примере, приведенном в этой статье у страницы одна структура, у ваших страниц она будет совершенно другая. Значит и скрипт который «обходит» элементы на ней будет совсем не такой как у меня. Мне же в этой статье хотелось бы донести до читателя принцип переноса данных со страницы в инфоблок.

расположение элементов FAQ на странице

На нашей странице расположено несколько блоков с вопросами и ответами на них. В каждом блоке таблица из нескольких ячеек, в которых выводятся: вопрос, ответ на него, а также дополнительные критерии вопроса. Наша задача поместить всю эту информацию в элемент инфоблока Битрикса.

Этот процесс будет организован следующим образом: мы напишем JS-скрипт, который будет «обходить» в цикле все элементы с «вопросами-ответами» и сохранять данные в свойствах JS-объекта, предварительно очистив их от ненужного HTML-кода и других лишних символов. Затем каждый объект передается посредством AJAX серверному скрипту, который будет создавать новый элемент инфоблока и сохранять туда значения свойств объекта.

На самом деле сделать все это несложно, но нужно быть внимательным и следить за корректной обработкой текста в таблице и результатом, который сохранится в элементе инфоблока.

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

На странице с которой мы будем работать, находятся FAQ по работе с бухгалтерской программой. Значит, секцию инфоблока так и назовем: «Бухгалтерия». В процессе создания секции ей был присвоен ID равный 95.

Свойства инфоблока и секция в админке

Теперь давайте рассмотрим таблицу с «вопросом-ответом» в качестве элемента инфоблока “FAQ”.

Схема таблицы FAQ с именами полей и свойств

Из рисунка видно, как мы планируем хранить данные: текст вопроса будет храниться в поле PREVIEW_TEXT, текст ответа в поле DETAIL_TEXT, а для критериев вопроса мы добавим 3 свойства с именами: PLATFORM, PROGRAMM и REALISE. Все поля будут текстового типа.

Теперь давайте будем разбираться с JS-скриптом, который будет парсить таблицы на нашей странице и отправлять данные на сервер.

Весь JS-код организован в виде 2 функций-конструкторов, состоящих из нескольких полезных функций.

  1. QABlock — будет обрабатывать отдельный элемент таблицы и создавать JS-объект, в свойствах которого сохранять: текст вопроса, текст ответа, а также значение атрибутов (в нашем примере — это платформа, программа, релиз). В качестве аргументов она получает селектор ячеек таблиц с «вопросами-ответами», а в результате возвращает объект;
  2. QABlockConstructor — будет находить на странице все таблицы с «вопросами-ответами», обходить их в цикле и каждую таблицу передавать в первую функцию. Полученный в результате работы функции QABlock объект, будет передаваться AJAX'ом серверному скрипту для сохранения его в информационном блоке. В качестве аргументов получает jQuery-селектор ячеек таблиц с «вопросами-ответами» (которые потом передает в QABlock), ИД инфоблока, ИД секции инфоблока, а также путь к серверному скрипту. Возвращает ответ от сервера об успешном добавлении или об ошибке.

Еще раз напомню, что код напрямую зависит от структуры страницы. Приведенный ниже код подходит именно для нашей страницы.

JavaScript

//конструктор одного элемента
function QABlock(p){
    var o = this;
    this.root = $(p.root); // table
    this.cells = $(p.cells, this.root); // td

    // массив данных для сохранения
    var arrData = new Object();

    this.parseTxtFromCells = function(){
        // текст вопроса
        arrData.iQuest = o.cells.eq(1).html();
        // текст ответа
        arrData.iAnsw = o.cells.eq(4).html();
        // текст свойства
        var propsTxt = o.cells.eq(2).text();
        propsTxt = $.trim(propsTxt);

        var r_exp = /:\s+|:|\s{2,}/g;

        propsTxt = propsTxt.replace(r_exp, '\t');

        var props = new Array();
        props = propsTxt.split(/\t\s*/);
		
	 /*
        // для отладки 
        for (var i = 0; i < props.length; i++){
            	console.log(i + ' ' + props[i]);
        }*/
		
        arrData.prop_platform = props[1];
        arrData.prop_programm = props[3];
        arrData.prop_realise = props[5];
		
	 /*
       // для отладки
	 console.log('Вопрос: ' + arrData.iQuest);
        console.log('Ответ: ' + arrData.iAnsw);
        console.log('Свойства');
        console.log('Платформа: ' + arrData.prop_platform);
        console.log('Программа: ' + arrData.prop_programm);
        console.log('Релиз: ' + arrData.prop_realise);
	 console.log('============================');
	*/
		
       return arrData;
    }

    this.init = function(){
        var questInfo = o.parseTxtFromCells();
        return questInfo;
    }
}

Итак, о том что происходит в функции QABlock по порядку: выбираем все ячейки таблицы и создаем новый пустой объект с именем arrData. В объекте создаем поля (iQuest и iAnsw) и заполняем их текстом вопроса и ответа. Атрибуты вопроса также хранятся в виде текста в ячейке, а нам нужно чтобы каждый атрибут хранился в отдельном свойстве объекта. Сначала сохраним их в переменной propsTxt. С помощь метода split и регулярного выражения превращаем атрибуты в элементы массива props, а затем сохраняем их в свойствах объекта arrData (prop_platform, prop_programm, prop_realise).

Важно убедиться, что этот код работает корректно, потому что в будущем мы его будем вызывать в другой функции.

Давайте подключим его к нашей странице и выведем результат его работы в консоли браузера, используя console.log. Для этого просто раскомментируйте приведенный выше код, создайте объект и вызовите метод init().

Вы можете вывести в консоль все объекты, созданные на основе данных со страницы:

JavaScript

$(function(){
    var itemTable;
	   
    $('#faqsWrapper>div').each(function(index){
	  itemTable = new QABlock({
	     root: $(this).children('table'),
	     cells: 'td',
	  });
	  itemTable.init();
    });
});

Или только один, созданный на основе первой таблицы:

JavaScript

$(function(){
     var fstBlock = new QABlock({
           root: $('#faqsWrapper>div:eq(0) table'),
           cells: 'td'
     });
     
     fstBlock.init();
});

Если все сделано правильно на этом этапе, в консоли вы увидите картину, похожую на следующую.

Результат работы скрипта в консоли браузера

Теперь давайте рассмотрим вторую функцию-конструктор, которая называется QABlockConstructor.

JavaScript

	// конструктор для создания объектов вопросов и отправки их на сервер
	function QABlockConstructor(p){
		var o = this;
		this.elset = $(p.elset); // набор вопросов table

		this.elsetLength = this.elset.length;

		this.elcell = p.elcell; 

		// инфоблок
		var iblockID = p.iblockID;

		// секция инфоблока
		this.curSect = p.curSect;
	
		this.scriptPath = p.scriptPath;
		
		// отправка данных через AJAX
		this.saveFAQData = function(q){
			$.ajax({
				url: o.scriptPath,
				type: 'POST',
				data:{
					AJAX: 'Y',
					iblockID: o.iblockID,
					iblockSection: o.curSect,
					questText: q.iQuest,
					answText: q.iAnsw,
					pPlatform: q.prop_platform,
					pProgramm: q.prop_programm,
					pRealise: q.prop_realise
				},
				success: function(txt){
					console.log(txt);
				},
			});
		}

		//инициализация
		this.init = function(){
			
			if(o.elsetLength > 0){
				console.log('Всего элементов на странице: ' + o.elsetLength);
				o.elset.each(function(index){
					var quest = new QABlock({
						root: $(this),
						cells: o.elcell
					});

					var questDataObj = quest.init();
					o.saveFAQData(questDataObj);				
				});
			}
			else{
				console.log('Нет подходящих элементов на странице!');
				return false;
			}			
		}
	}

Функции-конструкторы поместим в файл parser.js и подключим его к нашей странице exmpl.php.

Перед подключением скрипта не забудьте подключить библиотеку jQuery.

PHP

CJSCore::Init(array("jquery"));
$APPLICATION->AddHeadScript('/faq/parser.js');

Теперь перейдем к серверному скрипту. Назовем его faq_import.php. Выглядит он следующим образом.

PHP

// подключение служебной части пролога
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
header('Content-type: text/html; charset=utf-8');

if(isset($_POST["AJAX"]) && $_POST["AJAX"] == "Y"){

    CModule::IncludeModule('iblock');
    // создаем объект
        $el = new CIBlockElement;

    // params
        $iblockID = intVal($_POST["iblockID"]);

    // Секция
        $iblockSection = intVal($_POST["iblockSection"]);

        $clear_quest = strip_tags($_POST["questText"]);

        // может быть не удалять только <br> из текста вопроса
        //$clear_quest = strip_tags($_POST["questText"], "<br>");


        if(strlen($clear_quest) > 250){
            $tmpQuestName = mb_substr($clear_quest, 0, 250);
            $lastbarpos = mb_strrpos($tmpQuestName, " ");
            $questName = trim(mb_substr($tmpQuestName, 0, $lastbarpos))."…";            
        }
        else{
            $questName = trim($clear_quest);
        }

    //очищаем от тегов кроме <br>
       $questTextClear = strip_tags($_POST["questText"], '<br>');
    // Вопрос - анонс
        $questText = trim($questTextClear);
    // Ответ - подробно
        $answText = trim($_POST["answText"]);

    // element properties
        $PROPS = Array();
        $PROPS["PLATFORM"] = trim($_POST["pPlatform"]); // Платформа (70)
        $PROPS["PROGRAMM"] = trim($_POST["pProgramm"]); // Программа (71)
        $PROPS["REALISE"] = trim($_POST["pRealise"]); // Релиз (72)

        $arrLoadFAQArray = Array(
            "IBLOCK_ID" => $iblockID,
            "IBLOCK_SECTION_ID" => $iblockSection,
            "ACTIVE" => "Y",
            "NAME" => $questName,
            "PREVIEW_TEXT_TYPE" => "html",
            "PREVIEW_TEXT" => $questText,
            "DETAIL_TEXT_TYPE" => "html",
            "DETAIL_TEXT" => $answText,
            "PROPERTY_VALUES" => $PROPS
        );

    // добавляем
        if($PRODUCT_ID = $el->Add($arrLoadFAQArray))
            echo "Добавлен новый элемент с ID: ".$PRODUCT_ID;
        else
            echo "Ошибка при добавлении: ".$el->LAST_ERROR;
}
else{
    showError("Скрипт не работает без параметров!");
}

// подключение служебной части эпилога
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_after.php");

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

Теперь давайте запустим процесс переноса FAQ со страницы в инфоблок — разместим на странице exmpl.php следующий код, создающий на странице объект qb с параметрами и вызовем его метод init.

JavaScript

$(function(){	   
   var qb = new QABlockConstructor({
     elset: '#faqsWrapper>div table',
     elcell: 'td',
     iblockID: 13, // ID инфоблока
     curSect: 95, // ID секции
     scriptPath: 'faq_import.php',
   });
   qb.init();
});

Откроем страницу в браузере и если все сделано правильно, в инфоблоке “FAQ” появятся новые элементы, а в консоли вы увидите сообщения, аналогичные показанным на изображении.

Результат работы скрипта faq_import.php в консоли

Добавленные элементы в инфоблоке

Итак, задача выполнена. Весь текст находится в инфоблоке. Теперь можно вывести его на страницу с помощью компонента CMS и подходящего для вас шаблона. Надеюсь, что эта статья будет полезна читателю и поможет при решении аналогичных задач по переносу статической информации в информационный блок.

Скачать примеры кода из статьи

Прочитано 7438 раз
Свежие заметки
Наверх