iwgt 2.4.11 → 2.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data/references/commonjs-complete-guide.json +1082 -0
- package/dist/data/references/commonjs-reference.json +1 -1
- package/dist/data/references/liquid-filters.json +1 -1
- package/dist/data/references/liquid-variables.json +1 -1
- package/dist/generators/index.js +5 -0
- package/dist/server-http.js +1 -1
- package/dist/server.js +1 -1
- package/dist/tools/index.js +14 -5
- package/package.json +1 -1
|
@@ -0,0 +1,1082 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "3.0.0",
|
|
3
|
+
"title": "Полный справочник CommonJS API v2 для InSales",
|
|
4
|
+
"description": "Библиотека common.v2.js создана для минимизации JavaScript кода. Большинство функций работают через data-атрибуты БЕЗ написания JS.",
|
|
5
|
+
"generatedAt": "2025-01-08",
|
|
6
|
+
"critical_info": {
|
|
7
|
+
"no_imports": "⚠️ ВСЕ модули доступны ГЛОБАЛЬНО через window. НЕ НУЖНО использовать import!",
|
|
8
|
+
"declarative_first": "✅ ИСПОЛЬЗУЙТЕ data-атрибуты вместо JavaScript где возможно",
|
|
9
|
+
"lodash_not_global": "⚠️ Lodash НЕ глобальный! Он импортируется внутри модулей CommonJS. В виджетах используйте нативный JS или jQuery.",
|
|
10
|
+
"jquery_global": "✅ jQuery доступен глобально как $ и jQuery"
|
|
11
|
+
},
|
|
12
|
+
"installation": {
|
|
13
|
+
"method": "liquid_tag",
|
|
14
|
+
"code": "{% include_insales_scripts \"common-js@v2\" %}",
|
|
15
|
+
"alternative": "Добавить \"common_js_version\": \"v2\" в settings_data.json",
|
|
16
|
+
"note": "В шаблонах 4 поколения common-js указывается в качестве зависимости для виджетов"
|
|
17
|
+
},
|
|
18
|
+
"global_variables": {
|
|
19
|
+
"description": "Все эти переменные доступны глобально через window. НЕ ИМПОРТИРУЙТЕ их!",
|
|
20
|
+
"list": [
|
|
21
|
+
{
|
|
22
|
+
"name": "Cart",
|
|
23
|
+
"alias": "InsalesCommonCart",
|
|
24
|
+
"type": "object",
|
|
25
|
+
"description": "Управление корзиной магазина. Алиас для InsalesCommonCart.",
|
|
26
|
+
"usage": "Cart.add({ items: { 123456: 1 } })",
|
|
27
|
+
"no_import": true
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "Products",
|
|
31
|
+
"type": "object",
|
|
32
|
+
"description": "Управление товарами, вариантами и опциями",
|
|
33
|
+
"usage": "Products.get(123456).done(function(product) { ... })",
|
|
34
|
+
"no_import": true
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "EventBus",
|
|
38
|
+
"type": "object",
|
|
39
|
+
"description": "Шина событий для взаимодействия между компонентами",
|
|
40
|
+
"usage": "EventBus.subscribe('add_items:insales:cart', function(data) { ... })",
|
|
41
|
+
"no_import": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "Compare",
|
|
45
|
+
"type": "object",
|
|
46
|
+
"description": "Управление списком сравнения товаров",
|
|
47
|
+
"usage": "Compare.add({ item: 123456 })",
|
|
48
|
+
"no_import": true
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "FavoritesProducts",
|
|
52
|
+
"type": "object",
|
|
53
|
+
"description": "Управление списком избранных товаров",
|
|
54
|
+
"usage": "FavoritesProducts.add({ item: 123456 })",
|
|
55
|
+
"no_import": true
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "ajaxAPI",
|
|
59
|
+
"type": "object",
|
|
60
|
+
"description": "API для работы с данными магазина через AJAX",
|
|
61
|
+
"usage": "ajaxAPI.cart.get().done(function(cart) { ... })",
|
|
62
|
+
"no_import": true
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "Shop",
|
|
66
|
+
"type": "object",
|
|
67
|
+
"description": "Вспомогательные методы магазина (форматирование цен, конфигурация)",
|
|
68
|
+
"usage": "Shop.money.format(1234.00)",
|
|
69
|
+
"no_import": true
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "Template",
|
|
73
|
+
"type": "object",
|
|
74
|
+
"description": "Lodash шаблонизатор для работы с динамическими данными",
|
|
75
|
+
"usage": "Template.render({ title: 'Hello' }, 'my-template')",
|
|
76
|
+
"no_import": true
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "AjaxSearch",
|
|
80
|
+
"type": "object",
|
|
81
|
+
"description": "Живой поиск по товарам",
|
|
82
|
+
"usage": "AjaxSearch.setConfig({ letters: 3, delay: 300 })",
|
|
83
|
+
"no_import": true
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "Tools",
|
|
87
|
+
"type": "object",
|
|
88
|
+
"description": "Набор вспомогательных утилит",
|
|
89
|
+
"usage": "Tools.getLinkCurrentLang(link, lang)",
|
|
90
|
+
"no_import": true
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "localforage",
|
|
94
|
+
"type": "object",
|
|
95
|
+
"description": "Библиотека для работы с локальным хранилищем",
|
|
96
|
+
"usage": "localforage.getItem('key')",
|
|
97
|
+
"no_import": true
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "InSalesUI",
|
|
101
|
+
"type": "object",
|
|
102
|
+
"description": "UI утилиты для работы с интерфейсом",
|
|
103
|
+
"usage": "InSalesUI.openQuickCheckoutModal()",
|
|
104
|
+
"no_import": true
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"name": "Site",
|
|
108
|
+
"type": "object",
|
|
109
|
+
"description": "Объект для хранения данных сайта",
|
|
110
|
+
"usage": "Site.myData = { ... }",
|
|
111
|
+
"no_import": true
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"name": "$",
|
|
115
|
+
"alias": "jQuery",
|
|
116
|
+
"type": "function",
|
|
117
|
+
"description": "jQuery библиотека доступна глобально",
|
|
118
|
+
"usage": "$('.selector').addClass('active')",
|
|
119
|
+
"no_import": true
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
"declarative_ui": {
|
|
124
|
+
"description": "Декларативный UI через data-атрибуты. Работает БЕЗ JavaScript!",
|
|
125
|
+
"philosophy": "CommonJS создан чтобы разработчики писали МЕНЬШЕ JavaScript. Большинство функций реализовано через data-атрибуты.",
|
|
126
|
+
"products": {
|
|
127
|
+
"description": "Управление товарами через data-атрибуты",
|
|
128
|
+
"attributes": [
|
|
129
|
+
{
|
|
130
|
+
"name": "data-product-id",
|
|
131
|
+
"required": true,
|
|
132
|
+
"value": "ID товара",
|
|
133
|
+
"description": "Обязательный атрибут для инициализации товара",
|
|
134
|
+
"example": "<form data-product-id=\"{{ product.id }}\" action=\"{{ cart_url }}\" method=\"post\">",
|
|
135
|
+
"works_without_js": true
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"name": "data-product-variants",
|
|
139
|
+
"value": "JSON с настройками отображения",
|
|
140
|
+
"description": "Селектор вариантов товара с разными видами отображения",
|
|
141
|
+
"example": "<select name=\"variant_id\" data-product-variants='{\"default\": \"option-radio\", \"Цвет\": \"option-preview\"}'></select>",
|
|
142
|
+
"works_without_js": false,
|
|
143
|
+
"options": ["option-select", "option-radio", "option-span", "option-preview", "option-preview-text", "option-select-image"]
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"name": "data-quantity",
|
|
147
|
+
"required": true,
|
|
148
|
+
"description": "Обертка для кнопок изменения количества и input",
|
|
149
|
+
"example": "<div data-quantity>\n <button data-quantity-change=\"-1\">-</button>\n <input type=\"text\" name=\"quantity\" value=\"1\" />\n <button data-quantity-change=\"1\">+</button>\n</div>",
|
|
150
|
+
"works_without_js": false
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"name": "data-quantity-change",
|
|
154
|
+
"value": "число (например: 1, -1)",
|
|
155
|
+
"description": "Кнопки изменения количества +/-",
|
|
156
|
+
"example": "<button data-quantity-change=\"1\">+</button>",
|
|
157
|
+
"works_without_js": false
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"name": "data-item-add",
|
|
161
|
+
"description": "Кнопка добавления товара в корзину",
|
|
162
|
+
"example": "<button type=\"submit\" data-item-add>Добавить в корзину</button>",
|
|
163
|
+
"works_without_js": false,
|
|
164
|
+
"events": ["add_items:insales:cart", "update_items:insales:cart"]
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"name": "data-product-card-price",
|
|
168
|
+
"description": "Цена продажи варианта товара. Автоматически обновляется при смене варианта",
|
|
169
|
+
"example": "<span data-product-card-price></span>",
|
|
170
|
+
"works_without_js": false
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "data-product-card-old-price",
|
|
174
|
+
"description": "Старая цена варианта товара",
|
|
175
|
+
"example": "<span data-product-card-old-price></span>",
|
|
176
|
+
"works_without_js": false
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "data-product-card-sku",
|
|
180
|
+
"value": "JSON с настройками",
|
|
181
|
+
"description": "Артикул варианта товара с опциональным label",
|
|
182
|
+
"example": "<span data-product-card-sku='{\"skuLabel\": \"Артикул:\"}'></span>",
|
|
183
|
+
"works_without_js": false
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"name": "data-product-card-available",
|
|
187
|
+
"value": "JSON с текстами",
|
|
188
|
+
"description": "Наличие варианта товара",
|
|
189
|
+
"example": "<span data-product-card-available='{\"availableText\": \"В наличии\", \"notAvailableText\": \"Нет в наличии\"}'></span>",
|
|
190
|
+
"works_without_js": false
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"name": "data-add-cart-counter",
|
|
194
|
+
"value": "JSON с настройками",
|
|
195
|
+
"description": "Комплексный компонент: кнопка добавления + счетчик + кнопки +/-. Используется в шаблонах 4 поколения",
|
|
196
|
+
"example": "<div data-add-cart-counter='{\"step\": \"1\"}'>\n <button data-add-cart-counter-btn>В корзину</button>\n <div class=\"controls\">\n <button data-add-cart-counter-minus>-</button>\n <span data-add-cart-counter-count></span>\n <button data-add-cart-counter-plus>+</button>\n </div>\n</div>",
|
|
197
|
+
"works_without_js": false,
|
|
198
|
+
"css_class": "is-add-cart",
|
|
199
|
+
"note": "Автоматически добавляет класс .is-add-cart когда товар в корзине"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"name": "data-quick-checkout",
|
|
203
|
+
"value": "селектор формы товара",
|
|
204
|
+
"description": "Кнопка быстрого заказа (заказ в 1 клик)",
|
|
205
|
+
"example": "<button data-quick-checkout=\"[data-product-id='{{ product.id }}']\">Купить в 1 клик</button>",
|
|
206
|
+
"works_without_js": false
|
|
207
|
+
}
|
|
208
|
+
],
|
|
209
|
+
"events": [
|
|
210
|
+
{
|
|
211
|
+
"name": "init_instance:insales:product",
|
|
212
|
+
"description": "Срабатывает после инициализации формы товара",
|
|
213
|
+
"data": "{ product, variant, action }"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"name": "change_variant:insales:product",
|
|
217
|
+
"description": "Срабатывает при выборе варианта товара",
|
|
218
|
+
"data": "{ variant, first_image, action }"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"name": "update_variant:insales:product",
|
|
222
|
+
"description": "Обновление варианта товара",
|
|
223
|
+
"data": "{ variant, action }"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"name": "change_quantity:insales:product",
|
|
227
|
+
"description": "Изменение количества товара",
|
|
228
|
+
"data": "{ quantity, action }"
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
},
|
|
232
|
+
"cart": {
|
|
233
|
+
"description": "Управление корзиной через data-атрибуты",
|
|
234
|
+
"attributes": [
|
|
235
|
+
{
|
|
236
|
+
"name": "data-cart-form",
|
|
237
|
+
"required": true,
|
|
238
|
+
"description": "Обязательный атрибут для формы корзины",
|
|
239
|
+
"example": "<form data-cart-form action=\"{{ cart_url }}\" method=\"post\">",
|
|
240
|
+
"works_without_js": true
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"name": "data-item-id",
|
|
244
|
+
"required": true,
|
|
245
|
+
"value": "ID позиции в корзине",
|
|
246
|
+
"description": "Обязательный атрибут для позиций в корзине",
|
|
247
|
+
"example": "<div data-item-id=\"{{ item.id }}\">",
|
|
248
|
+
"works_without_js": true
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"name": "data-item-delete",
|
|
252
|
+
"value": "ID позиции",
|
|
253
|
+
"description": "Кнопка удаления позиции из корзины",
|
|
254
|
+
"example": "<button data-item-delete=\"{{ item.id }}\">Удалить</button>",
|
|
255
|
+
"works_without_js": false,
|
|
256
|
+
"events": ["delete_items:insales:cart"]
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"name": "data-cart-clear",
|
|
260
|
+
"description": "Кнопка полной очистки корзины",
|
|
261
|
+
"example": "<button data-cart-clear>Очистить корзину</button>",
|
|
262
|
+
"works_without_js": false,
|
|
263
|
+
"events": ["clear_items:insales:cart"]
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
"name": "data-cart-total-price",
|
|
267
|
+
"description": "Итоговая цена всех позиций БЕЗ учета скидок. Автоматически обновляется",
|
|
268
|
+
"example": "<span data-cart-total-price></span>",
|
|
269
|
+
"works_without_js": false
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"name": "data-cart-full-total-price",
|
|
273
|
+
"description": "Итоговая цена всех позиций С учетом скидок",
|
|
274
|
+
"example": "<span data-cart-full-total-price></span>",
|
|
275
|
+
"works_without_js": false
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"name": "data-cart-positions-count",
|
|
279
|
+
"description": "Количество позиций в корзине",
|
|
280
|
+
"example": "<span data-cart-positions-count></span>",
|
|
281
|
+
"works_without_js": false
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
"name": "data-cart-item-count",
|
|
285
|
+
"description": "Общее количество товаров в корзине",
|
|
286
|
+
"example": "<span data-cart-item-count></span>",
|
|
287
|
+
"works_without_js": false
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
"name": "data-cart-item-price",
|
|
291
|
+
"description": "Цена одной единицы позиции",
|
|
292
|
+
"example": "<span data-cart-item-price></span>",
|
|
293
|
+
"works_without_js": false
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"name": "data-cart-item-total-price",
|
|
297
|
+
"description": "Итоговая цена позиции (цена × количество)",
|
|
298
|
+
"example": "<span data-cart-item-total-price></span>",
|
|
299
|
+
"works_without_js": false
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"name": "data-coupon-submit",
|
|
303
|
+
"description": "Кнопка применения купона",
|
|
304
|
+
"example": "<button data-coupon-submit>Применить купон</button>",
|
|
305
|
+
"works_without_js": false,
|
|
306
|
+
"events": ["set_coupon:insales:cart"]
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"name": "data-cart-discounts-ajax",
|
|
310
|
+
"description": "Контейнер для вывода информации о скидках",
|
|
311
|
+
"example": "<div data-cart-discounts-ajax></div>",
|
|
312
|
+
"works_without_js": false,
|
|
313
|
+
"note": "Требует data-reload-on-coupon=\"false\" в форме"
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
"name": "data-cart-discounts-error",
|
|
317
|
+
"description": "Контейнер для вывода ошибок при применении купона",
|
|
318
|
+
"example": "<div data-cart-discounts-error></div>",
|
|
319
|
+
"works_without_js": false
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"name": "data-reload-on-coupon",
|
|
323
|
+
"value": "true/false",
|
|
324
|
+
"description": "Перезагружать ли страницу после применения купона. По умолчанию true",
|
|
325
|
+
"example": "<form data-cart-form data-reload-on-coupon=\"false\">",
|
|
326
|
+
"works_without_js": false
|
|
327
|
+
}
|
|
328
|
+
],
|
|
329
|
+
"events": [
|
|
330
|
+
{
|
|
331
|
+
"name": "add_items:insales:cart",
|
|
332
|
+
"description": "Товары добавлены в корзину",
|
|
333
|
+
"data": "{ items, order_lines, total_price, ... }"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"name": "update_items:insales:cart",
|
|
337
|
+
"description": "Корзина обновлена",
|
|
338
|
+
"data": "{ order_lines, total_price, items_count, ... }"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"name": "delete_items:insales:cart",
|
|
342
|
+
"description": "Товары удалены из корзины",
|
|
343
|
+
"data": "{ order_lines, total_price, ... }"
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
"name": "clear_items:insales:cart",
|
|
347
|
+
"description": "Корзина полностью очищена",
|
|
348
|
+
"data": "{ order_lines: [] }"
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"name": "set_coupon:insales:cart",
|
|
352
|
+
"description": "Купон применен",
|
|
353
|
+
"data": "{ coupon, discounts, ... }"
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"name": "before:insales:cart",
|
|
357
|
+
"description": "Перед любым действием с корзиной",
|
|
358
|
+
"data": "{ method, ... }"
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"name": "always:insales:cart",
|
|
362
|
+
"description": "После любого действия с корзиной",
|
|
363
|
+
"data": "{ method, ... }"
|
|
364
|
+
}
|
|
365
|
+
]
|
|
366
|
+
},
|
|
367
|
+
"favorites": {
|
|
368
|
+
"description": "Управление избранным через data-атрибуты",
|
|
369
|
+
"attributes": [
|
|
370
|
+
{
|
|
371
|
+
"name": "data-ui-favorites-add",
|
|
372
|
+
"value": "ID товара",
|
|
373
|
+
"description": "Кнопка добавления товара в избранное",
|
|
374
|
+
"example": "<button data-ui-favorites-add=\"{{ product.id }}\">В избранное</button>",
|
|
375
|
+
"works_without_js": false
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"name": "data-ui-favorites-delete",
|
|
379
|
+
"value": "ID товара",
|
|
380
|
+
"description": "Кнопка удаления товара из избранного",
|
|
381
|
+
"example": "<button data-ui-favorites-delete=\"{{ product.id }}\">Удалить</button>",
|
|
382
|
+
"works_without_js": false
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
"name": "data-ui-favorites-trigger",
|
|
386
|
+
"value": "ID товара",
|
|
387
|
+
"description": "Кнопка-переключатель (добавить/удалить)",
|
|
388
|
+
"example": "<button data-ui-favorites-trigger=\"{{ product.id }}\">♥</button>",
|
|
389
|
+
"works_without_js": false,
|
|
390
|
+
"css_classes": ["is-favorites-added", "is-favorites-not-added"]
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"name": "data-ui-favorites-counter",
|
|
394
|
+
"description": "Счетчик количества товаров в избранном",
|
|
395
|
+
"example": "<span data-ui-favorites-counter></span>",
|
|
396
|
+
"works_without_js": false
|
|
397
|
+
}
|
|
398
|
+
],
|
|
399
|
+
"events": [
|
|
400
|
+
{
|
|
401
|
+
"name": "add_item:insales:favorites_products",
|
|
402
|
+
"description": "Товар добавлен в избранное"
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"name": "remove_item:insales:favorites_products",
|
|
406
|
+
"description": "Товар удален из избранного"
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"name": "update_items:insales:favorites_products",
|
|
410
|
+
"description": "Список избранного обновлен"
|
|
411
|
+
}
|
|
412
|
+
]
|
|
413
|
+
},
|
|
414
|
+
"compare": {
|
|
415
|
+
"description": "Управление сравнением через data-атрибуты",
|
|
416
|
+
"attributes": [
|
|
417
|
+
{
|
|
418
|
+
"name": "data-compare-add",
|
|
419
|
+
"value": "ID товара",
|
|
420
|
+
"description": "Кнопка добавления товара в сравнение",
|
|
421
|
+
"example": "<button data-compare-add=\"{{ product.id }}\">Сравнить</button>",
|
|
422
|
+
"works_without_js": false
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
"name": "data-compare-delete",
|
|
426
|
+
"value": "ID товара",
|
|
427
|
+
"description": "Кнопка удаления товара из сравнения",
|
|
428
|
+
"example": "<button data-compare-delete=\"{{ product.id }}\">Удалить</button>",
|
|
429
|
+
"works_without_js": false
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
"name": "data-compare-trigger",
|
|
433
|
+
"value": "ID товара",
|
|
434
|
+
"description": "Кнопка-переключатель сравнения",
|
|
435
|
+
"example": "<button data-compare-trigger=\"{{ product.id }}\">⚖</button>",
|
|
436
|
+
"works_without_js": false,
|
|
437
|
+
"css_classes": ["is-compare-added", "is-compare-not-added"]
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"name": "data-compare-counter",
|
|
441
|
+
"description": "Счетчик товаров в сравнении",
|
|
442
|
+
"example": "<span data-compare-counter></span>",
|
|
443
|
+
"works_without_js": false
|
|
444
|
+
}
|
|
445
|
+
],
|
|
446
|
+
"events": [
|
|
447
|
+
{
|
|
448
|
+
"name": "add_item:insales:compares",
|
|
449
|
+
"description": "Товар добавлен в сравнение"
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"name": "remove_item:insales:compares",
|
|
453
|
+
"description": "Товар удален из сравнения"
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
"name": "update_items:insales:compares",
|
|
457
|
+
"description": "Список сравнения обновлен"
|
|
458
|
+
}
|
|
459
|
+
]
|
|
460
|
+
},
|
|
461
|
+
"forms": {
|
|
462
|
+
"description": "Формы обратной связи, отзывов, комментариев",
|
|
463
|
+
"feedback": {
|
|
464
|
+
"description": "Форма обратной связи с валидацией",
|
|
465
|
+
"attributes": [
|
|
466
|
+
{
|
|
467
|
+
"name": "data-feedback-form-wrapper",
|
|
468
|
+
"description": "Обертка формы обратной связи",
|
|
469
|
+
"example": "<form data-feedback-form-wrapper method=\"post\" action=\"/client_account/feedback\">",
|
|
470
|
+
"works_without_js": false
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"name": "data-feedback-form-field",
|
|
474
|
+
"value": "JSON с настройками",
|
|
475
|
+
"description": "Поле формы с валидацией",
|
|
476
|
+
"example": "<input name=\"phone\" data-feedback-form-field='{\"isRequired\": true, \"errorMessage\": \"Неверный телефон\", \"phoneNumberLength\": 11}' />",
|
|
477
|
+
"works_without_js": false,
|
|
478
|
+
"validation": ["isRequired", "phoneNumberLength", "errorMessage"]
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
"name": "data-feedback-form-field-error",
|
|
482
|
+
"description": "Контейнер для вывода ошибки поля",
|
|
483
|
+
"example": "<div data-feedback-form-field-error></div>",
|
|
484
|
+
"works_without_js": false
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
"name": "data-feedback-form-success",
|
|
488
|
+
"value": "JSON с настройками",
|
|
489
|
+
"description": "Сообщение об успешной отправке",
|
|
490
|
+
"example": "<div data-feedback-form-success='{\"showTime\": 10000}'>Спасибо!</div>",
|
|
491
|
+
"works_without_js": false
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
"name": "data-feedback-form-agree",
|
|
495
|
+
"value": "JSON с настройками",
|
|
496
|
+
"description": "Чекбокс согласия на обработку данных",
|
|
497
|
+
"example": "<input type=\"checkbox\" data-feedback-form-agree='{\"errorMessage\": \"Необходимо согласие\"}' />",
|
|
498
|
+
"works_without_js": false
|
|
499
|
+
}
|
|
500
|
+
]
|
|
501
|
+
}
|
|
502
|
+
},
|
|
503
|
+
"navigation": {
|
|
504
|
+
"description": "Навигация и меню",
|
|
505
|
+
"attributes": [
|
|
506
|
+
{
|
|
507
|
+
"name": "data-navigation",
|
|
508
|
+
"description": "Обертка навигационного меню",
|
|
509
|
+
"example": "<div data-navigation>",
|
|
510
|
+
"works_without_js": false
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
"name": "data-navigation-item",
|
|
514
|
+
"description": "Элемент меню",
|
|
515
|
+
"example": "<div data-navigation-item>",
|
|
516
|
+
"works_without_js": false
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"name": "data-navigation-link",
|
|
520
|
+
"value": "URL",
|
|
521
|
+
"description": "Ссылка в меню",
|
|
522
|
+
"example": "<a data-navigation-link=\"{{ link.url }}\">{{ link.title }}</a>",
|
|
523
|
+
"works_without_js": false
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
"name": "data-navigation-submenu",
|
|
527
|
+
"description": "Подменю",
|
|
528
|
+
"example": "<div data-navigation-submenu>",
|
|
529
|
+
"works_without_js": false
|
|
530
|
+
}
|
|
531
|
+
]
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
"javascript_api": {
|
|
535
|
+
"description": "JavaScript API для программного управления",
|
|
536
|
+
"note": "Используйте только когда data-атрибуты недостаточно!",
|
|
537
|
+
"Cart": {
|
|
538
|
+
"description": "Управление корзиной программно",
|
|
539
|
+
"global": true,
|
|
540
|
+
"methods": [
|
|
541
|
+
{
|
|
542
|
+
"name": "add",
|
|
543
|
+
"signature": "Cart.add({ items, comments, coupon })",
|
|
544
|
+
"description": "Добавить товары в корзину",
|
|
545
|
+
"parameters": {
|
|
546
|
+
"items": "{ variant_id: quantity } или { accessoriable_variant_ids: {...} }",
|
|
547
|
+
"comments": "{ variant_id: 'комментарий' }",
|
|
548
|
+
"coupon": "строка с купоном"
|
|
549
|
+
},
|
|
550
|
+
"returns": "Promise",
|
|
551
|
+
"example": "Cart.add({\n items: { 123456: 2, 123457: 1 },\n comments: { 123456: 'Красный цвет' },\n coupon: 'SALE10'\n});",
|
|
552
|
+
"events": ["add_items:insales:cart", "update_items:insales:cart"]
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
"name": "delete",
|
|
556
|
+
"signature": "Cart.delete({ items })",
|
|
557
|
+
"description": "Удалить позиции из корзины",
|
|
558
|
+
"parameters": {
|
|
559
|
+
"items": "массив ID вариантов [123456, 123457]"
|
|
560
|
+
},
|
|
561
|
+
"example": "Cart.delete({ items: [123456, 123457] });",
|
|
562
|
+
"events": ["delete_items:insales:cart"]
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
"name": "clear",
|
|
566
|
+
"signature": "Cart.clear()",
|
|
567
|
+
"description": "Полностью очистить корзину",
|
|
568
|
+
"example": "Cart.clear();",
|
|
569
|
+
"events": ["clear_items:insales:cart"]
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
"name": "set",
|
|
573
|
+
"signature": "Cart.set({ items })",
|
|
574
|
+
"description": "Установить количество для позиций",
|
|
575
|
+
"parameters": {
|
|
576
|
+
"items": "{ variant_id: quantity }"
|
|
577
|
+
},
|
|
578
|
+
"example": "Cart.set({ items: { 123456: 3 } });",
|
|
579
|
+
"events": ["set_items:insales:cart"]
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
"name": "setCoupon",
|
|
583
|
+
"signature": "Cart.setCoupon({ coupon })",
|
|
584
|
+
"description": "Применить купон",
|
|
585
|
+
"example": "Cart.setCoupon({ coupon: 'SALE10' });",
|
|
586
|
+
"events": ["set_coupon:insales:cart"]
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
"name": "forceUpdate",
|
|
590
|
+
"signature": "Cart.forceUpdate()",
|
|
591
|
+
"description": "Принудительно обновить данные корзины",
|
|
592
|
+
"example": "Cart.forceUpdate();"
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
"name": "order.get",
|
|
596
|
+
"signature": "Cart.order.get()",
|
|
597
|
+
"description": "Получить текущее состояние корзины",
|
|
598
|
+
"returns": "объект с order_lines, total_price и т.д.",
|
|
599
|
+
"example": "var order = Cart.order.get();\nconsole.log(order.total_price);"
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
"name": "order.getItemByID",
|
|
603
|
+
"signature": "Cart.order.getItemByID(variantId)",
|
|
604
|
+
"description": "Получить позицию по ID варианта",
|
|
605
|
+
"example": "var item = Cart.order.getItemByID(123456);"
|
|
606
|
+
}
|
|
607
|
+
]
|
|
608
|
+
},
|
|
609
|
+
"Products": {
|
|
610
|
+
"description": "Управление товарами программно",
|
|
611
|
+
"global": true,
|
|
612
|
+
"methods": [
|
|
613
|
+
{
|
|
614
|
+
"name": "get",
|
|
615
|
+
"signature": "Products.get(productId)",
|
|
616
|
+
"description": "Получить информацию о товаре",
|
|
617
|
+
"returns": "Promise с данными товара",
|
|
618
|
+
"example": "Products.get(123456)\n .done(function(product) {\n console.log(product.title);\n });"
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
"name": "getList",
|
|
622
|
+
"signature": "Products.getList([productIds])",
|
|
623
|
+
"description": "Получить список товаров",
|
|
624
|
+
"note": "Максимум 700 товаров за раз. Товары кешируются в localStorage",
|
|
625
|
+
"example": "Products.getList([123456, 123457])\n .done(function(products) {\n console.log(products);\n });"
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
"name": "setConfig",
|
|
629
|
+
"signature": "Products.setConfig(options)",
|
|
630
|
+
"description": "Установить глобальные настройки для товаров",
|
|
631
|
+
"parameters": {
|
|
632
|
+
"showVariants": "boolean - показывать селектор вариантов",
|
|
633
|
+
"filtered": "boolean - скрывать недоступные опции",
|
|
634
|
+
"selectUnavailable": "boolean - разрешить выбор недоступного",
|
|
635
|
+
"useMax": "boolean - ограничить quantity доступным количеством"
|
|
636
|
+
},
|
|
637
|
+
"example": "Products.setConfig({\n showVariants: true,\n filtered: true,\n useMax: true\n});"
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
"name": "getInstance",
|
|
641
|
+
"signature": "Products.getInstance($node)",
|
|
642
|
+
"description": "Получить экземпляр ProductInstance из jQuery элемента",
|
|
643
|
+
"example": "Products.getInstance($('.product-form'))\n .done(function(instance) {\n console.log(instance.variant);\n });"
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
"name": "initInstance",
|
|
647
|
+
"signature": "Products.initInstance($node)",
|
|
648
|
+
"description": "Инициализировать форму товара",
|
|
649
|
+
"example": "Products.initInstance($('.product-form'));"
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
"name": "getRecentlyViewed",
|
|
653
|
+
"signature": "Products.getRecentlyViewed()",
|
|
654
|
+
"description": "Получить массив ID просмотренных товаров",
|
|
655
|
+
"returns": "Promise с массивом ID",
|
|
656
|
+
"example": "Products.getRecentlyViewed()\n .done(function(ids) {\n console.log(ids);\n });"
|
|
657
|
+
}
|
|
658
|
+
]
|
|
659
|
+
},
|
|
660
|
+
"EventBus": {
|
|
661
|
+
"description": "Шина событий для взаимодействия компонентов",
|
|
662
|
+
"global": true,
|
|
663
|
+
"philosophy": "Работает по принципу Pub/Sub. События срабатывают даже если подписка произошла после публикации.",
|
|
664
|
+
"methods": [
|
|
665
|
+
{
|
|
666
|
+
"name": "subscribe",
|
|
667
|
+
"signature": "EventBus.subscribe(eventId, callback)",
|
|
668
|
+
"description": "Подписаться на событие",
|
|
669
|
+
"example": "EventBus.subscribe('add_items:insales:cart', function(data) {\n console.log('Товар добавлен:', data);\n});"
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
"name": "publish",
|
|
673
|
+
"signature": "EventBus.publish(eventId, data)",
|
|
674
|
+
"description": "Опубликовать событие",
|
|
675
|
+
"example": "EventBus.publish('my:custom:event', { test: true });"
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
"name": "unsubscribe",
|
|
679
|
+
"signature": "EventBus.unsubscribe(eventId, callback)",
|
|
680
|
+
"description": "Отписаться от события",
|
|
681
|
+
"example": "EventBus.unsubscribe('add_items:insales:cart', myCallback);"
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
"name": "logger.add",
|
|
685
|
+
"signature": "EventBus.logger.add(componentName)",
|
|
686
|
+
"description": "Добавить логирование для компонента",
|
|
687
|
+
"components": ["cart", "product", "search", "compares", "favorites_products"],
|
|
688
|
+
"example": "EventBus.logger.add('cart');"
|
|
689
|
+
}
|
|
690
|
+
],
|
|
691
|
+
"common_events": [
|
|
692
|
+
"add_items:insales:cart",
|
|
693
|
+
"update_items:insales:cart",
|
|
694
|
+
"delete_items:insales:cart",
|
|
695
|
+
"clear_items:insales:cart",
|
|
696
|
+
"change_variant:insales:product",
|
|
697
|
+
"change_quantity:insales:product",
|
|
698
|
+
"add_item:insales:compares",
|
|
699
|
+
"add_item:insales:favorites_products"
|
|
700
|
+
]
|
|
701
|
+
},
|
|
702
|
+
"Compare": {
|
|
703
|
+
"description": "Управление сравнением программно",
|
|
704
|
+
"global": true,
|
|
705
|
+
"methods": [
|
|
706
|
+
{
|
|
707
|
+
"name": "add",
|
|
708
|
+
"signature": "Compare.add({ item: productId })",
|
|
709
|
+
"description": "Добавить товар в сравнение",
|
|
710
|
+
"example": "Compare.add({ item: 123456 });"
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
"name": "remove",
|
|
714
|
+
"signature": "Compare.remove({ item: productId })",
|
|
715
|
+
"description": "Удалить товар из сравнения",
|
|
716
|
+
"example": "Compare.remove({ item: 123456 });"
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"name": "clear",
|
|
720
|
+
"signature": "Compare.clear()",
|
|
721
|
+
"description": "Очистить список сравнения",
|
|
722
|
+
"example": "Compare.clear();"
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"name": "getCompare",
|
|
726
|
+
"signature": "Compare.getCompare()",
|
|
727
|
+
"description": "Получить текущее состояние сравнения",
|
|
728
|
+
"returns": "объект с products",
|
|
729
|
+
"example": "var state = Compare.getCompare();\nconsole.log(state.products);"
|
|
730
|
+
}
|
|
731
|
+
]
|
|
732
|
+
},
|
|
733
|
+
"FavoritesProducts": {
|
|
734
|
+
"description": "Управление избранным программно",
|
|
735
|
+
"global": true,
|
|
736
|
+
"methods": [
|
|
737
|
+
{
|
|
738
|
+
"name": "add",
|
|
739
|
+
"signature": "FavoritesProducts.add({ item: productId })",
|
|
740
|
+
"description": "Добавить товар в избранное",
|
|
741
|
+
"example": "FavoritesProducts.add({ item: 123456 });"
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
"name": "remove",
|
|
745
|
+
"signature": "FavoritesProducts.remove({ item: productId })",
|
|
746
|
+
"description": "Удалить товар из избранного",
|
|
747
|
+
"example": "FavoritesProducts.remove({ item: 123456 });"
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
"name": "clear",
|
|
751
|
+
"signature": "FavoritesProducts.clear()",
|
|
752
|
+
"description": "Очистить избранное",
|
|
753
|
+
"example": "FavoritesProducts.clear();"
|
|
754
|
+
},
|
|
755
|
+
{
|
|
756
|
+
"name": "getFavoritesProducts",
|
|
757
|
+
"signature": "FavoritesProducts.getFavoritesProducts()",
|
|
758
|
+
"description": "Получить текущее состояние избранного",
|
|
759
|
+
"returns": "объект с products",
|
|
760
|
+
"example": "var state = FavoritesProducts.getFavoritesProducts();"
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
"name": "update",
|
|
764
|
+
"signature": "FavoritesProducts.update()",
|
|
765
|
+
"description": "Обновить состояние избранного",
|
|
766
|
+
"example": "FavoritesProducts.update();"
|
|
767
|
+
}
|
|
768
|
+
]
|
|
769
|
+
},
|
|
770
|
+
"Shop": {
|
|
771
|
+
"description": "Вспомогательные методы магазина",
|
|
772
|
+
"global": true,
|
|
773
|
+
"methods": [
|
|
774
|
+
{
|
|
775
|
+
"name": "money.format",
|
|
776
|
+
"signature": "Shop.money.format(amount)",
|
|
777
|
+
"description": "Форматировать цену согласно настройкам магазина",
|
|
778
|
+
"returns": "строка с отформатированной ценой",
|
|
779
|
+
"example": "Shop.money.format(1234.50); // '1 234,50 руб.'"
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
"name": "config.getProductId",
|
|
783
|
+
"signature": "Shop.config.getProductId()",
|
|
784
|
+
"description": "Получить ID товара на текущей странице",
|
|
785
|
+
"returns": "number или null",
|
|
786
|
+
"example": "var productId = Shop.config.getProductId();"
|
|
787
|
+
},
|
|
788
|
+
{
|
|
789
|
+
"name": "config.get",
|
|
790
|
+
"signature": "Shop.config.get()",
|
|
791
|
+
"description": "Получить конфигурацию магазина",
|
|
792
|
+
"returns": "объект с настройками",
|
|
793
|
+
"example": "var config = Shop.config.get();"
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
"name": "units.getName",
|
|
797
|
+
"signature": "Shop.units.getName(unit)",
|
|
798
|
+
"description": "Получить название единицы измерения",
|
|
799
|
+
"example": "Shop.units.getName('kgm'); // 'кг'"
|
|
800
|
+
}
|
|
801
|
+
]
|
|
802
|
+
},
|
|
803
|
+
"ajaxAPI": {
|
|
804
|
+
"description": "API для AJAX запросов к серверу",
|
|
805
|
+
"global": true,
|
|
806
|
+
"cart": {
|
|
807
|
+
"add": "ajaxAPI.cart.add(items, options)",
|
|
808
|
+
"get": "ajaxAPI.cart.get()",
|
|
809
|
+
"update": "ajaxAPI.cart.update(items, options)",
|
|
810
|
+
"remove": "ajaxAPI.cart.remove(variantId)"
|
|
811
|
+
},
|
|
812
|
+
"product": {
|
|
813
|
+
"get": "ajaxAPI.product.get(productId)",
|
|
814
|
+
"getList": "ajaxAPI.product.getList([productIds])"
|
|
815
|
+
},
|
|
816
|
+
"shop": {
|
|
817
|
+
"message": "ajaxAPI.shop.message(feedback)",
|
|
818
|
+
"review": "ajaxAPI.shop.review(review, productUrl)",
|
|
819
|
+
"comment": "ajaxAPI.shop.comment(comment, articleUrl)"
|
|
820
|
+
},
|
|
821
|
+
"compare": {
|
|
822
|
+
"add": "ajaxAPI.compare.add(productId)",
|
|
823
|
+
"get": "ajaxAPI.compare.get()",
|
|
824
|
+
"remove": "ajaxAPI.compare.remove(productId)"
|
|
825
|
+
},
|
|
826
|
+
"favorites": {
|
|
827
|
+
"add": "ajaxAPI.favorites.add(productId)",
|
|
828
|
+
"get": "ajaxAPI.favorites.get()",
|
|
829
|
+
"remove": "ajaxAPI.favorites.remove(productId)"
|
|
830
|
+
}
|
|
831
|
+
},
|
|
832
|
+
"Template": {
|
|
833
|
+
"description": "Lodash шаблонизатор",
|
|
834
|
+
"global": true,
|
|
835
|
+
"methods": [
|
|
836
|
+
{
|
|
837
|
+
"name": "load",
|
|
838
|
+
"signature": "Template.load(templateBody, templateId)",
|
|
839
|
+
"description": "Загрузить шаблон",
|
|
840
|
+
"example": "Template.load('<div><%= title %></div>', 'my-template');"
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
"name": "render",
|
|
844
|
+
"signature": "Template.render(data, templateId)",
|
|
845
|
+
"description": "Отрендерить шаблон с данными",
|
|
846
|
+
"returns": "HTML строка",
|
|
847
|
+
"example": "var html = Template.render({ title: 'Hello' }, 'my-template');"
|
|
848
|
+
}
|
|
849
|
+
]
|
|
850
|
+
},
|
|
851
|
+
"AjaxSearch": {
|
|
852
|
+
"description": "Живой поиск по товарам",
|
|
853
|
+
"global": true,
|
|
854
|
+
"methods": [
|
|
855
|
+
{
|
|
856
|
+
"name": "setConfig",
|
|
857
|
+
"signature": "AjaxSearch.setConfig(options)",
|
|
858
|
+
"description": "Настроить поиск",
|
|
859
|
+
"parameters": {
|
|
860
|
+
"letters": "с какого символа начинать поиск",
|
|
861
|
+
"delay": "задержка между запросами (мс)",
|
|
862
|
+
"hide_items_out_of_stock": "скрывать товары не в наличии"
|
|
863
|
+
},
|
|
864
|
+
"example": "AjaxSearch.setConfig({\n letters: 3,\n delay: 300,\n hide_items_out_of_stock: true\n});"
|
|
865
|
+
}
|
|
866
|
+
]
|
|
867
|
+
},
|
|
868
|
+
"InSalesUI": {
|
|
869
|
+
"description": "UI утилиты",
|
|
870
|
+
"global": true,
|
|
871
|
+
"methods": [
|
|
872
|
+
{
|
|
873
|
+
"name": "openQuickCheckoutModal",
|
|
874
|
+
"signature": "InSalesUI.openQuickCheckoutModal()",
|
|
875
|
+
"description": "Открыть модальное окно быстрого заказа"
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
"name": "initAjaxInstance",
|
|
879
|
+
"signature": "InSalesUI.initAjaxInstance($node)",
|
|
880
|
+
"description": "Инициализировать AJAX корзину"
|
|
881
|
+
}
|
|
882
|
+
]
|
|
883
|
+
}
|
|
884
|
+
},
|
|
885
|
+
"best_practices": {
|
|
886
|
+
"title": "Лучшие практики использования CommonJS",
|
|
887
|
+
"rules": [
|
|
888
|
+
{
|
|
889
|
+
"rule": "НЕ импортируйте модули",
|
|
890
|
+
"description": "Все модули доступны глобально. Используйте Cart, Products, EventBus напрямую.",
|
|
891
|
+
"bad": "import { Cart } from 'common-js'; // ❌ НЕ ДЕЛАЙТЕ ТАК",
|
|
892
|
+
"good": "Cart.add({ items: { 123456: 1 } }); // ✅ Правильно"
|
|
893
|
+
},
|
|
894
|
+
{
|
|
895
|
+
"rule": "Используйте data-атрибуты вместо JS",
|
|
896
|
+
"description": "CommonJS создан чтобы минимизировать JavaScript код",
|
|
897
|
+
"bad": "$('.add-to-cart').on('click', function() {\n // много кода...\n}); // ❌",
|
|
898
|
+
"good": "<button data-item-add>В корзину</button> // ✅"
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
"rule": "Подписывайтесь на события",
|
|
902
|
+
"description": "Используйте EventBus для реакции на действия пользователя",
|
|
903
|
+
"good": "EventBus.subscribe('add_items:insales:cart', function(data) {\n console.log('Товар добавлен');\n});"
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
"rule": "Lodash не глобальный",
|
|
907
|
+
"description": "Используйте нативный JS или jQuery вместо Lodash в виджетах",
|
|
908
|
+
"bad": "_.forEach(items, function(item) { ... }); // ❌",
|
|
909
|
+
"good": "items.forEach(function(item) { ... }); // ✅\n// или\n$.each(items, function(i, item) { ... }); // ✅"
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
"rule": "Оборачивайте код в DOMContentLoaded",
|
|
913
|
+
"description": "Убедитесь что DOM загружен перед использованием API",
|
|
914
|
+
"good": "$(document).ready(function() {\n // ваш код\n});\n// или\n$(function() {\n // ваш код\n});"
|
|
915
|
+
},
|
|
916
|
+
{
|
|
917
|
+
"rule": "Используйте $widget для изоляции",
|
|
918
|
+
"description": "В виджетах используйте $widget вместо глобальных селекторов",
|
|
919
|
+
"bad": "$('.button').on('click', ...); // ❌ Затронет все кнопки",
|
|
920
|
+
"good": "$widget.find('.button').on('click', ...); // ✅ Только в виджете"
|
|
921
|
+
}
|
|
922
|
+
]
|
|
923
|
+
},
|
|
924
|
+
"common_patterns": {
|
|
925
|
+
"title": "Частые паттерны использования",
|
|
926
|
+
"patterns": [
|
|
927
|
+
{
|
|
928
|
+
"name": "Добавление товара в корзину",
|
|
929
|
+
"description": "Самый простой способ - через data-атрибут",
|
|
930
|
+
"html": "<form data-product-id=\"{{ product.id }}\" action=\"{{ cart_url }}\" method=\"post\">\n <input type=\"hidden\" name=\"variant_id\" value=\"{{ product.variants.first.id }}\" />\n <input type=\"text\" name=\"quantity\" value=\"1\" />\n <button type=\"submit\" data-item-add>В корзину</button>\n</form>",
|
|
931
|
+
"js": "// JavaScript НЕ НУЖЕН! Все работает через data-атрибуты"
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
"name": "Реакция на добавление в корзину",
|
|
935
|
+
"description": "Показать уведомление после добавления товара",
|
|
936
|
+
"js": "EventBus.subscribe('add_items:insales:cart', function(data) {\n alert('Товар добавлен в корзину!');\n console.log('Добавлено товаров:', data.items);\n});"
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
"name": "Обновление счетчика корзины",
|
|
940
|
+
"description": "Автоматическое обновление через data-атрибут",
|
|
941
|
+
"html": "<a href=\"/cart_items\">\n Корзина (<span data-cart-positions-count></span>)\n</a>",
|
|
942
|
+
"js": "// JavaScript НЕ НУЖЕН! Счетчик обновляется автоматически"
|
|
943
|
+
},
|
|
944
|
+
{
|
|
945
|
+
"name": "Кнопка избранного с переключением",
|
|
946
|
+
"html": "<button data-ui-favorites-trigger=\"{{ product.id }}\" class=\"favorite-btn\">\n <span data-ui-favorites-trigger-not-added-text=\"В избранное\">В избранное</span>\n <span data-ui-favorites-trigger-added-text=\"В избранном\">В избранном</span>\n</button>",
|
|
947
|
+
"css": ".favorite-btn.is-favorites-added { color: red; }"
|
|
948
|
+
},
|
|
949
|
+
{
|
|
950
|
+
"name": "Счетчик с кнопкой добавления",
|
|
951
|
+
"description": "Компонент add-cart-counter для карточек товаров",
|
|
952
|
+
"html": "<div data-add-cart-counter='{\"step\": \"1\"}' class=\"add-cart-counter\">\n <button data-add-cart-counter-btn>В корзину</button>\n <div class=\"controls\">\n <button data-add-cart-counter-minus>-</button>\n <span data-add-cart-counter-count></span>\n <button data-add-cart-counter-plus>+</button>\n </div>\n</div>",
|
|
953
|
+
"css": ".add-cart-counter .controls { display: none; }\n.add-cart-counter.is-add-cart .controls { display: flex; }\n.add-cart-counter.is-add-cart button[data-add-cart-counter-btn] { display: none; }"
|
|
954
|
+
},
|
|
955
|
+
{
|
|
956
|
+
"name": "Получение данных товара",
|
|
957
|
+
"js": "Products.get(123456).done(function(product) {\n console.log('Название:', product.title);\n console.log('Цена:', product.variants[0].price);\n});"
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
"name": "Форматирование цены",
|
|
961
|
+
"js": "var formattedPrice = Shop.money.format(1234.50);\nconsole.log(formattedPrice); // '1 234,50 руб.'"
|
|
962
|
+
},
|
|
963
|
+
{
|
|
964
|
+
"name": "Цикл по виджетам",
|
|
965
|
+
"description": "На странице может быть несколько экземпляров виджета",
|
|
966
|
+
"js": "$widget.each(function(index, el) {\n // Работа с конкретным экземпляром виджета\n var $thisWidget = $(el);\n $thisWidget.find('.button').on('click', function() {\n // ...\n });\n});"
|
|
967
|
+
}
|
|
968
|
+
]
|
|
969
|
+
},
|
|
970
|
+
"troubleshooting": {
|
|
971
|
+
"title": "Частые проблемы и решения",
|
|
972
|
+
"issues": [
|
|
973
|
+
{
|
|
974
|
+
"problem": "Ошибка: Cart is not defined",
|
|
975
|
+
"solution": "Убедитесь что common-js подключен: {% include_insales_scripts \"common-js@v2\" %}",
|
|
976
|
+
"check": "Откройте консоль и проверьте: typeof Cart !== 'undefined'"
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
"problem": "Ошибка: _ is not defined (Lodash)",
|
|
980
|
+
"solution": "Lodash НЕ глобальный в CommonJS v2. Используйте нативный JS или jQuery",
|
|
981
|
+
"bad": "_.forEach(items, ...)",
|
|
982
|
+
"good": "items.forEach(...) или $.each(items, ...)"
|
|
983
|
+
},
|
|
984
|
+
{
|
|
985
|
+
"problem": "Data-атрибуты не работают",
|
|
986
|
+
"solution": "Проверьте что элементы находятся внутри правильного контейнера (например, data-product-id для товара)",
|
|
987
|
+
"check": "Убедитесь что форма имеет data-product-id или data-cart-form"
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
"problem": "События не срабатывают",
|
|
991
|
+
"solution": "Подписка на события должна быть после DOMContentLoaded",
|
|
992
|
+
"good": "$(document).ready(function() {\n EventBus.subscribe('add_items:insales:cart', ...);\n});"
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
"problem": "Виджет влияет на другие виджеты",
|
|
996
|
+
"solution": "Используйте $widget вместо глобальных селекторов",
|
|
997
|
+
"bad": "$('.button').on('click', ...)",
|
|
998
|
+
"good": "$widget.find('.button').on('click', ...)"
|
|
999
|
+
},
|
|
1000
|
+
{
|
|
1001
|
+
"problem": "Дубль корзины (2 версии common.js)",
|
|
1002
|
+
"solution": "Проверьте что подключена только одна версия common.js",
|
|
1003
|
+
"check": "Смотрите предупреждение в консоли: 'Возможен дубль корзины'"
|
|
1004
|
+
}
|
|
1005
|
+
]
|
|
1006
|
+
},
|
|
1007
|
+
"migration_from_v1": {
|
|
1008
|
+
"title": "Миграция с common.js v1",
|
|
1009
|
+
"changes": [
|
|
1010
|
+
{
|
|
1011
|
+
"change": "Lodash больше не глобальный",
|
|
1012
|
+
"v1": "_.forEach(items, ...)",
|
|
1013
|
+
"v2": "items.forEach(...) или $.each(items, ...)"
|
|
1014
|
+
},
|
|
1015
|
+
{
|
|
1016
|
+
"change": "Новые data-атрибуты для UI",
|
|
1017
|
+
"note": "Добавлены префиксы data-ui-* для избранного и сравнения"
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
"change": "EventBus вместо прямых callback",
|
|
1021
|
+
"v1": "Cart.add(items, function() { ... })",
|
|
1022
|
+
"v2": "Cart.add(items);\nEventBus.subscribe('add_items:insales:cart', function() { ... });"
|
|
1023
|
+
}
|
|
1024
|
+
]
|
|
1025
|
+
},
|
|
1026
|
+
"examples_from_real_widgets": {
|
|
1027
|
+
"title": "Примеры из реальных виджетов",
|
|
1028
|
+
"widgets": [
|
|
1029
|
+
{
|
|
1030
|
+
"name": "Карточка товара с вариантами",
|
|
1031
|
+
"file": "system_widget_v4_special_products_5",
|
|
1032
|
+
"key_features": [
|
|
1033
|
+
"Использование EventBus для подписки на события",
|
|
1034
|
+
"Цикл $widget.each для множественных экземпляров",
|
|
1035
|
+
"Обновление FavoritesProducts после загрузки",
|
|
1036
|
+
"Изменение изображения при смене варианта"
|
|
1037
|
+
],
|
|
1038
|
+
"code_snippet": "EventBus.subscribe('change_variant:insales:product', function(data) {\n if (data.first_image.url) {\n $(data.action.product[0])\n .find('.product-preview__photo img')\n .attr('src', data.first_image.medium_url);\n }\n});"
|
|
1039
|
+
},
|
|
1040
|
+
{
|
|
1041
|
+
"name": "Корзина с купоном",
|
|
1042
|
+
"file": "system_widget_v4_cart_2",
|
|
1043
|
+
"key_features": [
|
|
1044
|
+
"Использование data-атрибутов для управления",
|
|
1045
|
+
"Подписка на события корзины",
|
|
1046
|
+
"Работа с купонами через Cart.setCoupon",
|
|
1047
|
+
"Обработка удаления товаров"
|
|
1048
|
+
],
|
|
1049
|
+
"code_snippet": "EventBus.subscribe('delete_items:insales:cart', function(data) {\n if (data.order_lines.length == 0) {\n $cartForm.addClass('hidden');\n $emptyMessage.removeClass('hidden');\n }\n});"
|
|
1050
|
+
},
|
|
1051
|
+
{
|
|
1052
|
+
"name": "Сравнение товаров",
|
|
1053
|
+
"file": "system_widget_v4_compare_1",
|
|
1054
|
+
"key_features": [
|
|
1055
|
+
"Реакция на удаление через EventBus",
|
|
1056
|
+
"Работа с DOM после изменений",
|
|
1057
|
+
"Использование data-атрибутов для идентификации"
|
|
1058
|
+
],
|
|
1059
|
+
"code_snippet": "EventBus.subscribe('remove_item:insales:compares', function(data) {\n $('[data-compared-id=\"' + data.action.item + '\"]').remove();\n if (data.products.length == 0) {\n $('.js-compare-empty').removeClass('hidden');\n }\n});"
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
"name": "Шапка с фиксацией",
|
|
1063
|
+
"file": "system_widget_v4_header_19",
|
|
1064
|
+
"key_features": [
|
|
1065
|
+
"Работа с нативным JavaScript",
|
|
1066
|
+
"Использование jQuery для совместимости",
|
|
1067
|
+
"Подписка на события редактора виджетов"
|
|
1068
|
+
],
|
|
1069
|
+
"code_snippet": "EventBus.subscribe([\n 'widget:input-setting:insales:system:editor',\n 'widget:change-setting:insales:system:editor'\n], function() {\n // Обновление после изменения настроек\n});"
|
|
1070
|
+
}
|
|
1071
|
+
]
|
|
1072
|
+
},
|
|
1073
|
+
"meta": {
|
|
1074
|
+
"version": "3.0.0",
|
|
1075
|
+
"commonjs_version": "v2",
|
|
1076
|
+
"last_updated": "2025-01-08",
|
|
1077
|
+
"modules_count": 14,
|
|
1078
|
+
"data_attributes_count": 50,
|
|
1079
|
+
"events_count": 30,
|
|
1080
|
+
"methods_count": 45
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "2.0",
|
|
3
|
-
"generatedAt": "2025-10-
|
|
3
|
+
"generatedAt": "2025-10-22T12:01:25.425Z",
|
|
4
4
|
"description": "Справочник по библиотеке common.v2.js для InSales - набор готовых скриптов для разработки шаблонов",
|
|
5
5
|
"installation": {
|
|
6
6
|
"method": "liquid_tag",
|
package/dist/generators/index.js
CHANGED
|
@@ -259,6 +259,11 @@ export function generateSettingsForm(commonSettings) {
|
|
|
259
259
|
if (setting.clearable)
|
|
260
260
|
item.clearable = setting.clearable;
|
|
261
261
|
}
|
|
262
|
+
else if (setting.type === 'file') {
|
|
263
|
+
item.value = setting.value || null;
|
|
264
|
+
if (setting['with-generate-logo'])
|
|
265
|
+
item['with-generate-logo'] = setting['with-generate-logo'];
|
|
266
|
+
}
|
|
262
267
|
// Общие свойства
|
|
263
268
|
if (setting.help)
|
|
264
269
|
item.help = setting.help;
|
package/dist/server-http.js
CHANGED
package/dist/server.js
CHANGED
package/dist/tools/index.js
CHANGED
|
@@ -148,7 +148,12 @@ export function getLiquidFilters(args = {}) {
|
|
|
148
148
|
export function getCommonJSAPI(args = {}) {
|
|
149
149
|
const { category, module, search } = args;
|
|
150
150
|
const data = commonjsApiComplete;
|
|
151
|
-
|
|
151
|
+
// Получаем модули из global_modules
|
|
152
|
+
const globalModules = data.global_modules || {};
|
|
153
|
+
let modules = Object.keys(globalModules).map(key => ({
|
|
154
|
+
name: key,
|
|
155
|
+
...globalModules[key]
|
|
156
|
+
}));
|
|
152
157
|
if (module) {
|
|
153
158
|
modules = modules.filter((mod) => mod.name === module);
|
|
154
159
|
}
|
|
@@ -159,16 +164,20 @@ export function getCommonJSAPI(args = {}) {
|
|
|
159
164
|
const searchLower = search.toLowerCase();
|
|
160
165
|
modules = modules.filter((mod) => mod.name.toLowerCase().includes(searchLower) ||
|
|
161
166
|
mod.description?.toLowerCase().includes(searchLower) ||
|
|
162
|
-
mod.methods
|
|
167
|
+
(mod.methods && Object.keys(mod.methods).some((methodName) => methodName.toLowerCase().includes(searchLower))) ||
|
|
168
|
+
(mod.events && Object.keys(mod.events).some((eventName) => eventName.toLowerCase().includes(searchLower))));
|
|
163
169
|
}
|
|
164
170
|
return {
|
|
165
171
|
total: modules.length,
|
|
166
172
|
modules: modules.map((mod) => ({
|
|
167
173
|
name: mod.name,
|
|
168
174
|
description: mod.description,
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
175
|
+
global_access: mod.global_access,
|
|
176
|
+
type: mod.type,
|
|
177
|
+
declarative: mod.declarative,
|
|
178
|
+
methods: mod.methods || {},
|
|
179
|
+
events: mod.events || {},
|
|
180
|
+
data_attributes: mod.data_attributes || {}
|
|
172
181
|
}))
|
|
173
182
|
};
|
|
174
183
|
}
|