Выгрузка HTML описаний с картинками (Base64) товаров на сайт/интернет-магазин/B2B, разберем регулярное выражение получения тега body, ПолучитьHTML, ФорматированныйДокумент

24.02.21

Интеграция - Сайты и интернет-магазины

Редактор HTML платформы 1С простой и очень удобный для небольших задач, однако ПолучитьHTML возвращает отдельно картинки и отдельно целиком HTML страницу со ссылкой на имена этих картинок, что неудобно для отправки в базу данных сайта/интернет-магазина/веб-приложения/B2B. Разберем на открытом коде, как решить эту проблему, напишем универсальную функцию получения значения любого тега HTML на регулярных выражениях. Бонусом - возможность редактировать теги HTML в текстовом режиме.

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

В нашем конструкторе веб-приложений EDIbot (подсистема для 1С для создания Dashboard, B2B) тоже возникла необходимость использования в ячейках внутреннего HTML оформления шаблона, покажем на примере:

 

 

Или вот как эта карточка выглядит в вебе -   https://jsonwebapp.com/regexp/json, ссылка на JSON для песочницы.

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

Функция ПолучитьHTML()  возвращает нам HTML страницу со ссылками внутри неё на ключи картинок ("image001") и заполняет структуру вложений.  

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="format-detection" content="telephone=no" />
<style type="text/css">
body{margin:0;padding:8px;}
p{line-height:1.15;margin:0;white-space:pre-wrap;}
ol,ul{margin-top:0;margin-bottom:0;}
img{border:none;}
li>p{display:inline;}
</style>
</head>
<body>
<p style="text-align: left;"><span style="font-size: 26pt;font-weight: bold;">&lt;body[^&gt;]*&gt;((.|\n)*)&lt;\/body&gt;</span></p>
<p style="text-align: left;"><br></p>
<p style="text-align: left;"><img height="146" src="image001" style="border:none;" width="449"/></p>
</body>
</html>

Как выяснилось, нам это неудобно, и требуется: 

1.Получить значение тега <body> из HTML (без самого тега body), который нам возвращает ПолучитьHTML.

2.Преобразовать получаемые картинки в base64 и заменить на него ключи в теле HTML.

 

Давайте реализуем функцию, которая получает значение произвольного тега HTML без самого тега - ПолучитьЗначениеТегаHTML(HTML, "body").

Проще всего для этого использовать регулярные выражения, в данном случае, нам подойдёт - <body[^>]*>((.|\n)*)<\/body>.

Давайте разберем его:

  1. <body[^>]*> - означает, что нам нужно найти в тексте <body>, причем после слова body может идти любой символ, кроме >. Используем жадный алгоритм (без ?), квантификатор *, т.е. нам подходит ноль или более букв после слова body. В итоге алгоритм найдет и <body>, и <body style="max-width: 1920px;background-color: rgb(166,166,166);">
  2. ((.|\n)*) - означает, что нам подходит любой символ или перевод строки после тега <body>, используем также жадный алгоритм. Скобочки нужны, чтобы выделить значение в отдельную группу (без слова body), которую мы легко сможем получить используя SubMatches. Кстати, если надо найти все теги <p>, то нужно из жадного сделать ленивый, добавив знак вопроса - ((.|\n)*?).  
  3. <\/body> - означает, что шаблон завершается тегом </body>, символ \ экранирует символ /. 

Попробовать его работу можно на сайте - https://regex101.com/r/MCgzCo/1/

Итак, наша функция будет выглядеть следующим образом:

Функция ПолучитьЗначениеТегаHTML(HTML, Тег) экспорт
	
	Результат = HTML;
	
	РегулярноеВыражение = _ОбщегоНазначенияКлиентСервер.НовоеРегулярноеВыражение("<"+Тег+"[^>]*>((.|\n)*)<\/"+Тег+">", Истина, Истина, Истина);			
	
	Выражения = РегулярноеВыражение.Execute(HTML);	
	
	Если Выражения.Count()>0 И Выражения.Item(0).SubMatches.Count()>0 Тогда		
		Результат = СокрЛП(Выражения.Item(0).SubMatches.Item(0));		
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

 

 

В результате обработки этой функцией нашего HTML мы получаем текст:

<p style="text-align: left;"><span style="font-size: 26pt;font-weight: bold;">&lt;body[^&gt;]*&gt;((.|\n)*)&lt;\/body&gt;</span></p>
<p style="text-align: left;"><br></p>
<p style="text-align: left;"><img height="146" src="image001" style="border:none;" width="449"/></p>

Здесь вставленная картинка описывается ключом ("image001") и отправка такой информации на сайт/интернет-магазин/веб-приложение приведёт к отображению страницы без картинки. Чтобы исправить такое положение дел, мы воспользуемся заменой ключей картинок на их значение в формате base64, собственно вот реализация такой процедуры: 

Процедура ЗаменитьКартинкиНаBase64(HTML, ВложенияHTML, ОбратноеДействие=Ложь) экспорт
	
	Для Каждого Вложение Из ВложенияHTML Цикл
		
		Картинка = Вложение.Значение; ИмяКартинки = Вложение.Ключ;
		
		Попытка
			ПрефиксBase64 = ПолучитьПрефиксBase64(Картинка.Формат());
		Исключение
			Продолжить;
		КонецПопытки;
		
		Если ПустаяСтрока(ПрефиксBase64) Тогда
			Продолжить;
		КонецЕсли;	
		
		ДвоичныеДанныеФайла = Картинка.ПолучитьДвоичныеДанные();
		
		Если ОбратноеДействие Тогда
			HTML = СтрЗаменить(HTML, "src="""+ПрефиксBase64+Base64Строка(ДвоичныеДанныеФайла)+"""", "src="""+ИмяКартинки+"");
		Иначе	
			HTML = СтрЗаменить(HTML, "src="""+ИмяКартинки+"", "src="""+ПрефиксBase64+Base64Строка(ДвоичныеДанныеФайла)+"""");
		КонецЕсли;	
			
	КонецЦикла;	
	
КонецПроцедуры

 

Теперь мы можем построить нашу итоговую универсальную функцию по сохранению HTML, которая на вход получает форму, объект, вложения HTML и реквизиты формы (типа структура), используемые для HTML редактирования.

Процедура СохранитьHTMLПоля(Форма, Объект, СтруктураВложенийHTML, Реквизиты)экспорт
    
    Если СтруктураВложенийHTML=Неопределено Тогда
        СтруктураВложенийHTML = Новый Структура();
    КонецЕсли;
    
    Для Каждого Реквизит Из Реквизиты Цикл
        
        ВложенияHTMLРеквизита = Новый Структура();
        
        Форма[Реквизит.Значение].ПолучитьHTML(Объект[Реквизит.Ключ], ВложенияHTMLРеквизита);
        
        СтруктураВложенийHTML.Вставить(Реквизит.Ключ, ВложенияHTMLРеквизита);
        
        //сохраним только тело
        Объект[Реквизит.Ключ] = ПолучитьЗначениеТегаHTML(Объект[Реквизит.Ключ], "body");
        
        ЗаменитьКартинкиНаBase64(Объект[Реквизит.Ключ], ВложенияHTMLРеквизита);    
        
    КонецЦикла;    
    
КонецПроцедуры   

 

Пример вызова функции, например, из ПередЗаписьюНаСервере: _ВебАппHTML.СохранитьHTMLПоля(ЭтаФорма, ТекущийОбъект, ВложенияHTML, Новый Структура("_ОписаниеHTML", "_ОписаниеHTMLФорма"));

_ОписаниеHTML - это реквизит метаданных типа неограниченная строка

_ОписаниеHTMLФорма - это реквизит формы типа ФорматированныйДокумент.

 

 

Отлично, мы сохранили с Вами данные, а теперь при открытии в следующий раз их нужно восстановить, т.е. выполнить обратное действие по замене картинок на их ключи. Зачем? А чтобы мы могли потом редактировать теги HTML без пролистывания большого значения base64.

 

Для этого реализуем универсальную функцию  - ВосстановитьHTMLПоля(Форма, Объект, СтруктураВложенийHTML, Реквизиты).

Процедура ВосстановитьHTMLПоля(Форма, Объект, СтруктураВложенийHTML, Реквизиты) экспорт
	
	Если НЕ ТипЗнч(СтруктураВложенийHTML)=Тип("Структура") Тогда
		СтруктураВложенийHTML = Новый Структура();
	КонецЕсли;	
	
	ВложенияHTMLРеквизита = Неопределено;
	Для Каждого Реквизит Из Реквизиты Цикл
	
		СтруктураВложенийHTML.Свойство(Реквизит.Ключ, ВложенияHTMLРеквизита);
		Если НЕ ТипЗнч(ВложенияHTMLРеквизита)=Тип("Структура") Тогда
			ВложенияHTMLРеквизита = Новый Структура();
		КонецЕсли;	
		
		HTML = Объект[Реквизит.Ключ];
		
		ЗаменитьКартинкиНаBase64(HTML, ВложенияHTMLРеквизита, Истина);
		
		Форма[Реквизит.Значение].УстановитьHTML(HTML, ВложенияHTMLРеквизита); 
		
	КонецЦикла;
	
КонецПроцедуры

 

Бонусом, как и обещал, мы теперь с Вами можем переходить вот в такой режим редактирования:

 

 

Все это легко сделать с помощью разработанных ранее универсальных функций:

&НаСервере
Процедура УправлениеРедактированиемHTML()
	
	Если Объект._РежимРедактированияТекста Тогда
		
		ВложенияHTMLРеквизита = Новый Структура();
		_ОписаниеHTMLФорма.ПолучитьHTML(Объект._ОписаниеHTML, ВложенияHTMLРеквизита);

		Объект._ОписаниеHTML = _ВебАппHTML.ПолучитьЗначениеТегаHTML(Объект._ОписаниеHTML, "body");
		
		Если НЕ ТипЗнч(ВложенияHTML)=Тип("Структура") Тогда
			ВложенияHTML = Новый Структура();
		КонецЕсли;	
		
		ВложенияHTML.Вставить("_ОписаниеHTML", ВложенияHTMLРеквизита);
		
	Иначе
		
		_ОписаниеHTMLФорма.УстановитьHTML(Объект._ОписаниеHTML, ВложенияHTML._ОписаниеHTML);
		
	КонецЕсли;
			
КонецПроцедуры

 

UPD.

Функция НовоеРегулярноеВыражение(Паттерн = "", ИгнорироватьРегистр = Истина, МногострочныйРежим = Ложь, ВсеВхождения = Истина) экспорт
	
	РегулярноеВыражение = Новый COMОбъект("VBScript.RegExp");
	РегулярноеВыражение.Pattern    = Паттерн;
	РегулярноеВыражение.IgnoreCase = ИгнорироватьРегистр;
	РегулярноеВыражение.MultiLine  = МногострочныйРежим;
	РегулярноеВыражение.Global     = ВсеВхождения;
	
	Возврат РегулярноеВыражение;
	
КонецФункции

 

Надеюсь, моя публикация была Вам полезна и сэкономит Ваше время, ссылка на все публикации SizovE.

Подписывайтесь на мой канал (наверху), будет много интересного бесплатного контента :)

SizovE

См. также

Сайты и интернет-магазины Платформа 1С v8.3 1С:Розница 2 Розничная и сетевая торговля (FMCG) Россия Платные (руб)

Готовое интеграционное решение для оплаты покупок Долями в 1C:Розница 2.3. Реализовано в виде расширения. Интеграция сервиса dolyame.ru для приема платежей в рассрочку. Поддерживает работу от разных юридических лиц. Работа: в составе РИБ, отдельно от РИБ, тонкий, толстый клиент, web-клиент (через интернет-браузер).

22440 руб.

19.12.2023    5914    40    11    

37

Сайты и интернет-магазины WEB-интеграция Системный администратор Программист Пользователь Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    18355    20    22    

18

Сайты и интернет-магазины Платформа 1С v8.3 1С:Розница 2 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Управленческий учет Платные (руб)

Склад Вашего магазина онлайн в Telegram. С картинками, ценами, описанием и характеристиками. Используйте Telegram как торговую площадку и увеличивайте продажи.

54000 руб.

10.09.2024    974    2    4    

3

Сайты и интернет-магазины Платформа 1С v8.3 1С:Розница 3.0 Розничная и сетевая торговля (FMCG) Россия Платные (руб)

Готовое интеграционное решение для оплаты покупок Долями в 1C:Розница 3.0. Реализовано в виде расширения. Интеграция сервиса dolyame.ru для приема платежей в рассрочку. Поддерживает работу от разных юридических лиц. Работа: в составе РИБ, отдельно от РИБ, тонкий, толстый клиент, web-клиент (через интернет-браузер). Интегрировано в Чек ККМ, Рабочее место кассира (РМК)

24000 руб.

02.11.2024    684    2    0    

2

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс 24. Разработка имеет двухстороннюю синхронизацию 1С и Bitrix24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (платформа начиная с 8.3.23): 1С:Управление торговлей, 1С:Управление Нашей фирмой 3, 1С:Комплексная автоматизация 2, Объединенное решение: Модуль 1С:CRM 3 (3.0.21.3) +1С:ERP Управление предприятием 2. При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

7200 руб.

04.05.2021    20565    13    19    

18

Сайты и интернет-магазины Программист Бизнес-аналитик Пользователь Платформа 1С v8.3 Конфигурации 1cv8 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Управленческий учет Платные (руб)

Программа позволяет одним кликом настроить сбор цен ваших конкурентов или дилеров в интернете. Автоматически собирает данные результата поиска Яндекса (вам не придется вручную добавлять каждый сайт, за которым нужно следить). Обновление цен происходит по заданному вами расписанию автоматически. Можете легко отслеживать позиции вашего сайта в Яндексе по ключевым словам и фразам. Этот инструмент даст вам лучшее понимание того, как ваша SEO-стратегия влияет на видимость вашего сайта в поисковой выдаче, и поможет вам улучшить контент и структуру сайта для повышения его позиций. Функция доступна во всех тарифах.

19950 руб.

23.09.2019    31258    8    12    

31
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. AneJIbcuH 40 22.02.21 17:16 Сейчас в теме
Подскажите, а тут что за функция?
_ОбщегоНазначенияКлиентСервер.НовоеРегулярноеВыражение(
2. SizovE 272 24.02.21 10:19 Сейчас в теме
(1) Спасибо, забыл выложить
Функция НовоеРегулярноеВыражение(Паттерн = "", ИгнорироватьРегистр = Истина, МногострочныйРежим = Ложь, ВсеВхождения = Истина) экспорт
	
	РегулярноеВыражение = Новый COMОбъект("VBScript.RegExp");
	РегулярноеВыражение.Pattern    = Паттерн;
	РегулярноеВыражение.IgnoreCase = ИгнорироватьРегистр;
	РегулярноеВыражение.MultiLine  = МногострочныйРежим;
	РегулярноеВыражение.Global     = ВсеВхождения;
	
	Возврат РегулярноеВыражение;
	
КонецФункции
Показать
3. dimasts 22 16.04.21 23:13 Сейчас в теме
Как быть с картинками имеющими адрес такого типа?
"blob:applewebdata://97a79a97-c02b-4585-8339-fd38316054e7/44b6636c-7eab-494a-a09e-8731d7ee2e92"
Такой адрес имеют все картинки перетасканные в ПолеФорматированногоДокумента
Они не сохраняются при ПолученииHtml и даже при сохранении в ХранилищеЗначений, но агружаются при новом открытии документа.

при перезагрузке ТонкогоКлиента картинки исчезают.
4. SizovE 272 17.04.21 07:40 Сейчас в теме
(3) А Вы пробовали перетаскивать в другие редакторы? Например, зайти сюда, перетащить картинку http://suneditor.com/sample/index.html, посмотреть по кнопке </>, как будет там. Если гуд, то вот Вам как его подключить в одной из моих публикаций https://infostart.ru/1c/articles/1352459/
Оставьте свое сообщение