Вводные
- Нужно по запросу к HTTP сервису 1С формировать HTML страницы по шаблонам.
- Реализовать с возможностью запуска на windows
Вариант решения
Для запуска шаблонного процессора нужна исполняющая среда, самое простое для разворачивания это Node.js. Один из распространенных шаблонных процессоров под JS является Handlebars (ссылка). В качестве фреймворка использую Express 4 (ссылка), шаблоном для проверки работоспособности выбрал шаблон админ панели AdminLTE 3 (ссылка).
Общая схема

Набор пакетов проекта node.js
{
"name": "admin_lte_node",
"version": "1.0.0",
"description": "",
"main": "app.js",
"dependencies": {
"admin-lte": "^3.0.5",
"express": "^4.17.1",
"express-handlebars": "^5.1.0",
"hbs": "^4.1.1"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Сборка проекта node.js
Собирал пробный вариант по статьям https://metanit.com/web/nodejs/4.19.php
Первый вариант app.js с использованием статичных данных
const express = require("express");
const expressHbs = require("express-handlebars");
const hbs = require("hbs");
const app = express();
const port = 3000;
//--
app.engine("hbs", expressHbs(
{
layoutsDir: "views/layouts",
defaultLayout: "layout",
extname: "hbs"
}
))
app.set("view engine", "hbs");
hbs.registerPartials(__dirname + "/views/partials");
//--
app.use('/', express.static('./node_modules/admin-lte'));
//--
body = {
title: "Мои контакты",
email: "gavgav@mycorp.com",
phone: "+1234567890"
};
app.use("/contact", function(request, response){
response.render("contact", body);
});
app.use("/home", function(request, response){
response.render("home");
});
app.use("/starter", function(request, response){
response.render("starter", body);
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
Для пробы работы с AdminLTE из пакета взял файл "starter.html", он при запуске сервиса node доступен для проверки работы по ссылке http://localhost:3000/starter.html, выделил из него заголовок, подвал, контент часть. Основу перенес в layout.hbs.
<!DOCTYPE html>
<!--
This is a starter template page. Use this page to start your new project from
scratch. This page gets rid of all links and provides the needed markup only.
-->
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{{title}}</title>
<!-- Font Awesome Icons -->
<link rel="stylesheet" href="plugins/fontawesome-free/css/all.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="dist/css/adminlte.min.css">
<!-- Google Font: Source Sans Pro -->
<link href="/redirect.php?url=aHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PVNvdXJjZStTYW5zK1BybzozMDAsNDAwLDQwMGksNzAw" rel="stylesheet">
</head>
<body class="hold-transition sidebar-mini">
<div class="wrapper">
{{> menu}}
{{{body}}}
{{> footer}}
</div>
<!-- ./wrapper -->
<!-- REQUIRED SCRIPTS -->
<!-- jQuery -->
<script src="plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/adminlte.min.js"></script>
</body>
</html>
Проверил работоспособность по ссылке http://localhost:3000/starter. Блоки указанные в layout.hbs имеют доступ к переменным переданным для форматирования, для передачи в дочерние шаблоны используется конструкция "{{> contentHeader title=title}}" (ссылка).
Реализация со стороны 1С
Реализовал HTTP сервис в виде раширения.
Функция hb_starterGET(Запрос)
//-- формирование данных для шаблона
СоотвтетсвиеДанные = Новый Соответствие();
СоотвтетсвиеДанные.Вставить("template", "starter");
СоотвтетсвиеДанныеЗаполнения = Новый Соответствие();
СоотвтетсвиеДанные.Вставить("data", СоотвтетсвиеДанныеЗаполнения);
СоотвтетсвиеДанныеЗаполнения.Вставить("title", "Тестовый заголовок");
МассивДанные = Новый Массив;
СоотвтетсвиеДанныеЗаполнения.Вставить("arr_data", МассивДанные);
МассивДанные.Добавить("Элемент массива 1");
МассивДанные.Добавить("Элемент массива 2");
МассивДанные.Добавить("Элемент массива 3");
СтрокаДанные = В_JSON(СоотвтетсвиеДанные);
//-- формирование, отправка запроса
Заголовоки = Новый Соответствие();
Заголовоки.Вставить("Content-Type", "application/json");
ДополнительныеПараметры = Новый Структура();
ДополнительныеПараметры.Вставить("Заголовки", Заголовоки);
Ответ = КоннекторHTTP.Post("http://localhost:3000/handlebars", СтрокаДанные, ДополнительныеПараметры);
СтрокаОтвет = КоннекторHTTP.КакТекст(Ответ);
//-- формирование ответа
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки(СтрокаОтвет);
Возврат Ответ;
КонецФункции
Дополнение в node.js
Добавил в app.js обработчик запроса от 1С
app.use(express.json());
app.use("/handlebars", function(request, response){
response.render(request.body.template, request.body.data);
});
Перенес статические файлы (\dist, \plugins) из папки модуля admin-lte (\node_modules\admin-lte) в папку корневой страницы Apache и переделал в шаблонах ссылки с относительно страницы "dist/..." на относительно сервера "/dist/..".
Проверка работы
Запустил проект через командную строку "node app.js", перезапустил apache.
Запустил проверку из браузера.
В заголовке страницы вывелось "Тестовый заголовок" что соответствует отправленным из 1С данным.
В мониторе сети видно что картинки отдаются с 304, это автоматическая настройка apache.
Запуск в качестве сервиса
Для работы приложения node.js в постоянном варианте можно его установить как сервис windows. Для этого нужно установить пакет node-windows (ссылка), сформировать и запустить скрипт регистрации сервиса.
Итог
При использовании 1С в качестве бекенд HTTP сервера можно использовать современные процессоры шаблонизации, что позволит
- выделить работу с HTML версткой в отдельный блок без привязки к 1С
- что позволит с меньшими техническими трудностями работать верстальщикам
- при использовании компонентов шаблонов уменьшить стоимость перехода на генерацию HTML страниц вне 1С
- используя промежуточную базу с кешем данных
- реализуя sinle page application (SPA)
GitHub репозиторий проекта (ссылка)
Благодарю за внимание.