processObjectTypeParameterOfPugMixin
- Общее техническое наименование
- compoundParameter
- Русскоязычное имя
- Составной параметр
- Тип
- CompoundParameter
- rawParameter
- Русскоязычное наименование
- Необработанный параметр примеси
- Обязательное если
- Хотя бы одно свойство в «parameterPropertiesSpecification» объявлено как обязательное
- Тип
- ParsedJSON_Object
- parameterPropertiesSpecification
- Русскоязычное наименование
- Спецификация свойств параметра примеси
- Обязательное
- Да
- Тип
- RawObjectDataProcessor.PropertiesSpecification
- parameterNumber
- Русскоязычное наименование
- Номер параметра примеси
- Обязательное
- Да
- Тип
- number
- parameterName
- Русскоязычное наименование
- Имя параметра примеси
- Обязательное
- Да
- Тип
- string
- mixinName
- Русскоязычное наименование
- Имя примеси
- Обязательное
- Да
- Тип
- string
Валидирует и обрабатывает параметр Pug-примеси типа «объект».
Подобная функциональность востребована в случаях, когда с помощью Pug-примесей реализуются GUI-компоненты или другие фрагменты разметки с большим количеством настраиваемых свойств, некоторые из которых (а иногда и все) для корректной генерации HTML-кода должны соответствовать определённым ограничениям.
Problems
HTML-препроцессор Pug, как и встроенный в него JavaScript не являются статически типизированными языками. В случае с использованием Pug-примесей с параметрами это означает, что если параметры указаны неверно (количество параметров, или же их тип и т. д.), то об этом заранее никаким образом не будет сообщено разработчику. Но даже если в ходе преобразования Pug в HTML и возникнет ошибка, то часто оказывается неясно, что именно и где было нарушено, а иногда и вовсе будет просто сгенерирован отличный от желаемого HTML-код без ошибок, что может быть замечено лишь через длительное время. Особенно это критично, когда примеси поставляются сторонней библиотекой, а не написаны самостоятельно, в том числе и в случае с реализацией GUI-компонентов с помощью Pug-примесей.
Примитивное решение этой проблемы — проверка параметров на тип и другие свойства (такие как количество символов или множество чисел) с помощью нативного JavaScript-а:
mixin Example(foo, bar, baz)
-
if (typeof foo !== "string") {
throw new Error(
`Тип 1-ого параметра примеси "Example" должен быть строкой в то время как он имеет тип "${ typeof foo }".`
);
}
if (foo.length < 2) {
throw new Error("1-ый параметр примеси \"Example\" должен иметь как минимум 2 символа.");
}
if (typeof bar !== "number") {
throw new Error(
`Тип 2-ого параметра примеси "Example" должен быть числом в то время как он имеет тип "${ typeof bar }".`
);
}
if (!Number.isInteger(bar)) {
throw new Error("2-ой параметр примеси \"Example\" должен быть целым числом.");
}
if (bar < 10) {
throw new Error(
`2-ой параметр примеси "Example" имеет значение ${ bar } в то время как минимальное значение — 10.`
);
}
if (typeof baz !== "boolean") {
throw new Error(
`Тип 3-его параметра примеси "Example" должен быть булевским в то время как он имеет тип "${ typeof baz }".`
);
}
Как видно, валидация даже трёх параметров заняла достаточно объёмную часть кода Pug-примеси, при этом сообщения об ошибках шаблонные, потому в других примесях их почти без изменений придётся печатать каждый раз. А что, если параметров не 3, а 10 и больше? А что, если таких примесей — несколько десятков? Такая ситуация вполне реальная, потому что для среднего веб-приложения 20-30 GUI-компонентов с возможностью гибкой настройки через множество свойств — это норма, а потому подобная «ручная» проверка параметров будет занимать очень много времени, сил и строк кода.
Здесь возникает вопрос о едином механизме валидации параметров, который должен проверить их свойства и если что-то не так, то подробно логировать все нарушения (а не только первое из них). При этом вывод информации в терминал должен быть достаточно понятен для того, чтобы пользователь Pug-примеси мог самостоятельно и быстро устранить нарушения без траты времени на поиск нужной справки в документации.
The YDF solution
С использованием интеграции YDEE , в частности класса RawObjectDataProcessor была разработана функция processObjectTypeParameterOfPugMixin, которая, в соответствии с прямым переводом, обрабатывает один параметр типа «объект» Pug-примеси.
Инструмента для валидации произвольного количества параметров любого типа
(как в примере с +Example(foo, bar, baz)) разработано
не было, потому что примеси (как и функции) с
большим количеством параметров создают трудности как в их обслуживании, так и в использовании.
Например, в +Example("top", 2, false) непонятно, какой смысл имеют значения
2 и false, и даже если в
интегрированной среде разработки отображаются подсказки, то, например,
в GitHub или аналогичном сервисе при рецензировании кода их
не будет (да и то, это надо ещё поискать такой редактор кода или плагин, который
отображает имена параметров Pug-примесей).
К счастью, с JavaScript-подобным синтаксисом в Pug эту проблему легко решить,
объединив несколько параметров в один типа «объект»:
mixin Example(compoundParameter)
const { foo, bar, baz } = compoundParameter;
В примере выше с помощью деструктурирующего присваивания все
свойства параметра типа «объект» были вынесены в
константы и теперь ими
можно пользоваться как если бы это были отдельные параметры.
Используя processObjectTypeParameterOfPugMixin, деструктурировать нужно
не сам параметр (compoundParameter в
примере выше), а возвращаемое этой функцией значение:
mixin Example(compoundParameter)
const {
foo,
bar,
baz
} = processObjectTypeParameterOfPugMixin({
rawParameter: compoundParameter,
parameterNumber: 1,
parameterName: "compoundParameter",
parameterPropertiesSpecification: {
foo: {
type: String,
required: true,
minimalCharactersCount: 2
},
bar: {
type: Number,
numbersSet: RawObjectDataProcessor.NumbersSets.nonNegativeIngeter,
required: true,
minimalValue: 10
},
baz: {
type: Boolean,
required: true
}
},
mixinName: "Example"
});
Как видно, эта функция также принимает единственный
параметр типа «объект» — по тем же причинам, что описаны
выше для Pug-примесей.
Среди свойств этого объектного параметра есть и
rawParameter — именно через него необходимо передать
конкретный параметр Pug-примеси (в примере выше у
Pug-примеси параметр только один).
Другое важное свойство — parameterPropertiesSpecification;
в нём необходимо указать правила валидации, и, если нужно, то обработки (такие как подстановка значений по
умолчанию).
Свойство parameterPropertiesSpecification имеет тип
ObjectSubtypes.fixedKeyAndValuePairsObject — по сути это объект типа «ассоциативный массив», ключи
которого должны совпадать с ключами целевого
параметра Pug-примеси.
Остальные 3 свойства —
parameterNumber, parameterName и
mixinName предназначены исключительно для
логирования, однако они также важны, так как без их заполнения
может быть неясно, где именно произошло нарушение.
The Properties of the Sole Parameter
rawParameter
- Русскоязычное наименование
- Необработанный параметр примеси
- Обязательное если
- Хотя бы одно свойство в «parameterPropertiesSpecification» объявлено как обязательное
- Тип
- ParsedJSON_Object
Параметр Pug-примеси в исходном состоянии.
- Слово «raw» («сырой») здесь означает, что над этим параметром ещё не было проведено никаких манипуляций, таких как подстановка значений по умолчанию.
- Должен иметь тип «объект»,
валидация сразу же завершится с ошибкой.
Единственное исключение — когда все
свойства в
parameterPropertiesSpecificationобъявлены как необязательные, в этом случаеrawParameterможет быть иметь типundefined(в частности, быть не указанным при вызове примеси). ТогдаprocessObjectTypeParameterOfPugMixinзаменит этот пропущенный параметр на пустой объект, а также подставит значения по умолчанию, если таковые были указаны в параметреparameterPropertiesSpecification:
mixin Example(compoundParameter)
const {
foo,
bar
} = processObjectTypeParameterOfPugMixin({
rawParameter: compoundParameter,
parameterNumber: 1,
parameterName: "compoundParameter",
parameterPropertiesSpecification: {
foo: {
type: String,
required: false,
minimalCharactersCount: 2
},
bar: {
type: Number,
numbersSet: RawObjectDataProcessor.NumbersSets.nonNegativeIngeter,
defaultValue: 10
}
},
mixinName: "Example"
});parameterPropertiesSpecification
выше, свойство foo является необязательным,
а у bar есть значение по умолчанию.
Это значит, что = {} в
mixin Example(compoundParameter = {}) можно
опустить, так как
processObjectTypeParameterOfPugMixin сама создаст
пустой объект.
parameterPropertiesSpecification
- Русскоязычное наименование
- Спецификация свойств параметра примеси
- Обязательное
- Да
- Тип
- RawObjectDataProcessor.PropertiesSpecification
Правила валидации и обработки параметра rawParameter
Pug-примеси в формате
ObjectSubtypes.fixedKeyAndValuePairsObject.
По сути, это объект типа «ассоциативный массив», ключи
которого должны совпадать с ключами целевого параметра
Pug-примеси.
В значениях ассоциативного массива
ObjectSubtypes.fixedKeyAndValuePairsObject
есть много разных опций, но для каждого свойства примеси
необходимо указать нужно как минимум тип
(type) и обязательность required,
при этом когда планируется обеспечить значение по умолчанию, вместо
required нужно указать defaultValue.
Более подробную информацию об этих и других опциях Вы можете получить в
документации для RawObjectDataProcessor.
К сожалению ввиду того, что внутри Pug используется JavaScript,
а не TypeScript, при указании правил валидации велика
вероятность ошибки, что может привести к некорректному выполнению функции, а обнаружить это сразу
возможно не всегда.
Однако это не обесценивает использование
parameterPropertiesSpecification,
поэтому что наличие валидации лучше её отсутствия, а с
parameterPropertiesSpecification рутинного кода будет значительно
меньше, поскольку этой функции нужно лишь указать, что и по каким правилам валидировать
не занимаясь при этом реализаций валидации.
Чтобы снизить вероятность ошибки при определении правил валидации, можно в TypeScript-файле
объявить переменную типа ObjectSubtypes.fixedKeyAndValuePairsObject
и определить в ней все свойства, а затем вставить значение в Pug-код.
The Logging Properties — parameterNumber, parameterName, mixinName
- Русскоязычное наименование
- Номер параметра примеси
- Обязательное
- Да
- Тип
- number
- Русскоязычное наименование
- Имя параметра примеси
- Обязательное
- Да
- Тип
- string
- Русскоязычное наименование
- Имя примеси
- Обязательное
- Да
- Тип
- string
Используются исключительно для логирования ошибок валидации, если таковые будут допущены.
Номер параметра примеси — parameterNumber —
должен быть натуральным числом; остальные два свойства
должны иметь строчные значения.
Вот как, например, будет выглядеть фрагмент вывода в консоль при { parameterNumber: 1 },
{ parameterName: "properties" } и
{ mixinName: "Badge--YDF" }:
4| mixin Badge--YDF(properties)
5|
> 6| -
7|
8| const {
9|
Invalid parameter value
Object-type parameter No. 1 (named as "properties") of the Pug mixin "Badge--YDF" has one or more invalid properties:
(...)
Quick input in IntelliJ IDEA family of IDEs

Использование Live template-ов в семействе интегрированных сред разработки IntelliJ IDEA позволяет вводить код такой так выражения вызова функции быстрее. Для получения доступа к Live Template-ам библиотеки YDF потребуется установить официальный плагин этой библиотеки.
Steps for using the Live templates
Если Вы ранее не пользовались Live template-ами, то пусть Вас не пугает приведённая ниже объёмная инструкция: при сформированной привычке использования Live template-ов (эта привычка сходна с повседневным применением сочетаний клавиш) скорость выполнения описанных ниже операций займёт считанные секунды.
Перед тем, как начать использовать Live template, необходимо объявить Pug-примесь с указанием параметров либо нескольких таковых. Также, потребуется в теле примеси заготовить JavaScript-блок — все описанные ниже действия предстоит выполнять именно в нём.
- Начните набирать имя функции —
processObjectTypeParameterOfPugMixin. При текущей поддержке языка Pug интегрированная среда разработки, скорее всего, не будет знать о существовании функции processObjectTypeParameterOfPugMixin, если её нет среди файлов проекта (не включая зависимости вnode_modules), потому предложит только один вариант автодополнения. Но всё же если появилось два одноимённых варианта автодополнения — с буквой в центре круга и с клише, то выберете второй вариант. - Заполните свойство
rawParameterссылкой на нужный параметр примеси. Изначально будет предложено имяproperties, однако Ваш параметр Pug-примеси может иметь другое имя. Когда закончите — нажмите Enter. - Заполните свойство
parameterNumberномером целевого параметра примеси. Вам будет предложено выбрать число от 1 до 3 в выпадающем списке, потому если Ваш параметр имеет номер в этом диапазоне, то выберете нужное число с помощью клавиш со стрелками и нажмите Enter. Если же Ваш параметр имеет номер 4 или больше, то нажмите Esc, чтобы закрыть выпадающий список, введите нужное число и затем нажмитеEnter. - Заполните свойство
parameterNameименем целевого параметра и нажмитеEnter. - Заполните свойство
parameterPropertiesSpecificationобъектом типаObjectSubtypes.fixedKeyAndValuePairsObject. Чтобы снизить вероятность ошибки, которые могли быть тут же обнаружены при наличии статической типизации, рекомендуется создать переменную этого типа в TypeScript-файле и скопировать ещё значение сюда. Но разумеется, можно ввести код и напрямую. - Заполните свойство
mixinNameименем Вашей примеси.
External links
- Исходный код
- RawObjectDataProcessorКласс библиотеки «Yamato Daiwa E(CMA)Script Extensions», API которого используется функцией
processObjectTypeParameterOfPugMixin - Практический примерИспользование функции
processObjectTypeParameterOfPugMixinпри генерировании разметки Pug-примеси GUI-компонента«TextBox»