Всего 123 786 комментариев

Андрей Степаненко
17 апреля 2024, 06:19
+1
windows — страшная тема для docker) кто смог настроить docker под window, респект

Папка с build в 3 категории попадает

volumes:
    - "./Extras:/var/www/html/Extras"
    # Package
    - "./Extras/${PACKAGE_NAME}/core/components/${PACKAGE_NAME}:/var/www/html/core/components/${PACKAGE_NAME}:ro"
    - "./Extras/${PACKAGE_NAME}/assets/components/${PACKAGE_NAME}:/var/www/html/public/assets/components/${PACKAGE_NAME}:ro"
Директория для хранения самого пакета
/var/www/html/Extras

В нее затем уже с помощью команд обращаешься
#######################
# Extras package
#######################
package-build:
	docker compose exec app bash -c "export PACKAGE_DEPLOY=False && php Extras/${PACKAGE_NAME}/_build/build.php"

package-install:
	docker compose exec app bash -c "php ./docker/app/scripts/checking-add-ons.php"
	@make cache-clear

package-build-deploy:
	docker compose exec app bash -c "export PACKAGE_DEPLOY=True && php Extras/${PACKAGE_NAME}/_build/build.php"

package-target-clear:
	docker compose exec app bash -c 'rm -rf target/*'

package-deploy:
	@make package-target-clear
	@make package-build
	@make package-build-deploy

Volume core и assets

# Package
    - "./Extras/${PACKAGE_NAME}/core/components/${PACKAGE_NAME}:/var/www/html/core/components/${PACKAGE_NAME}:ro"
    - "./Extras/${PACKAGE_NAME}/assets/components/${PACKAGE_NAME}:/var/www/html/public/assets/components/${PACKAGE_NAME}:ro"
Эти volume прокидываются чтобы можно было редактировать код из Extras/${PACKAGE_NAME}
Wassi Wassinen
17 апреля 2024, 03:30
0
В таком формате для одной формы будет работать (если вставить в чанк формы)?

<script>
document.addEventListener('fetchit:success', (e) => {
  const { form } = e.detail;

  if (form.getAttribute('id') === 'main_form') {
      
    yaCounter96827878.reachGoal('course_main_form');

    
  }
});  
</script>
Wassi Wassinen
17 апреля 2024, 03:28
0
Было бы здорово, в таком формате (полный код для вставки в шаблон\чанк), показать это в документации. Наверное, это одна из самых частых задач для новичков. :)
Дима Касаткин
17 апреля 2024, 01:07
+2
А вообще, есть предложение ко всем, кто собирает MODX-пакеты!

Давайте в билдерах в папку ./_build/ вкладывать ещё подпапку с названием пакета
Сейчас структура папок:
./_build/build.config.php
./_build/…
./core/components/ModxExtraName/…
./assets/components/ModxExtraName/…

Предлагаю делать так:
./_build/ModxExtraName/build.config.php
./_build/ModxExtraName/…
./core/components/ModxExtraName/…
./assets/components/ModxExtraName/…

Это позволит не вычищать каждый раз _build перезаливкой другого пакета. Ведь организовать подпапку — это логично и красиво.

И даже не обязательно использовать modx-build-environment-gui, он просто сканирует папку _build, парсит версии для сборки и даёт список ссылок (гордо именуемый тем самым GUI), чтобы поменьше клавиатуру пальцами полировать :) но сам ничего больше и не делает. Даже ссылку на скачивание собранного транспортника уже выдаёт билдер самого пакета, если поддерживает согласно инструкции…

В общем так или иначе, круто что наконец мы добрались улучшать Developer Expierence! Чем проще создавать и поддерживать компоненты, тем лучше для экосистемы, и для сайтов, которые на поддержке, и для наших нервов ;)

P.S. Может перенести в заметки и раскрыть тему, есть желающие? Ставьте лайк, если интересно :)
Дима Касаткин
17 апреля 2024, 01:03
+1
Так и я не сравниваю, ты ведь в своём решении в Докер-ом предлагаешь вообще типа в режиме одноразовой копии запускать движок MODX для работы с пакетом, а файлы во внешней среде хранить как я понял. Это здорово! Но одно другому не мешает =)

Ну это к слову… А теперь к твоей теме: я сам на windows работаю, и докер локально не использую, но изучаю тему и поюзываю на серверах (как минимум потому что иногда другого не предлагается...). И вот читаю конфиги твои и есть вопрос: а почему ты не монтируешь в локальную папку директорию _build? Тебе же не только правки в код вносить, но и собрать надо пакет, или другой у тебя workflow?
Дима Касаткин
16 апреля 2024, 23:43
+1
Принимайте огромную благодарность от сообщества за то, что не просто снимаете компонент с продажи (как, увы, случается), а оставляете и переносите в общий доступ! Это вклад в развитие системы гораздо больше, чем кажется на первый взгляд. Респект!

P.S. Он теперь в копилке репозиториев MODX RSC будет, или исходники останутся закрытыми?
Денис Усманов
16 апреля 2024, 22:00
+1
Координаты можно в админпанели у ресурса в ТВ полях определять…
Для этого советую поставить компонент YandexCoordsTv

Так будет намного проще.
al1ve
16 апреля 2024, 21:56
0
а, я думал head, body — это ошибка по сео. Но с обычным скриптом тоже генерирует свои head, body. Тогда ладно. Кстати, я находил похожий код, где нужно вводить координаты и некоторые другие параметры. их вручную как то вычислять или где то прописаны? Я про myPlacemark, к примеру.

UPD: Всё, разобрался. Спасибо большое!
Денис Усманов
16 апреля 2024, 21:51
0
И вот тут уже немного иначе надо делать отложенную подгрузку, надо эти 2 скрипта подгружать уже не на место карты, а внизу сайта, рядом с остальными скриптами, насколько это всё работает, надо проверять…
Денис Усманов
16 апреля 2024, 21:49
0
Карта грузится в iframe, там свои head, body и т.п., это нормально.
Денис Усманов
16 апреля 2024, 21:48
+1
Код, представленный мной, подгружает карту Яндекс от их конструктора, но если делать по API, то там 2 скрипта нужно, первый — сам API

<script src="https://api-maps.yandex.ru/2.1/?load=package.full&lang=ru-RU" type="text/javascript"></script>

Второй, индивидуальные параметры карты, пример:

<script type="text/javascript">
    ymaps.ready(function() {
        var mapexMap = new ymaps.Map('map', {
                center: [55.721190, 52.440409],
                zoom: 16,
                controls: ['zoomControl']
            }),
        myPlacemark = new ymaps.Placemark(
            [55.721190, 52.440409], {
                "iconContent": "",
                "balloonContentBody": "423800, РТ, г.Набережные Челны, Промышленно-коммунальная зона, Индустриальный проезд, 62/21",
                "balloonContentHeader": "АО «КАМАтранссервис»"
            }, {
                // Опции.
                // Необходимо указать данный тип макета.
                iconLayout: 'default#image',
                // Своё изображение иконки метки.
                iconImageHref: '/assets/img/map-marker.png',
                // Размеры метки.
                iconImageSize: [30, 42],
                // Смещение левого верхнего угла иконки относительно
                // её "ножки" (точки привязки).
                iconImageOffset: [-5, -38]
            });
        mapexMap.behaviors.disable('scrollZoom');
        mapexMap.geoObjects.add(myPlacemark);

    });
</script>
al1ve
16 апреля 2024, 21:45
0
ну вроде работает, но почему то создаёт на всю ширину и ненужные теги в виде html, head, body. Если что — сам сайт smnu-vos.ru. Сама карта должна быть в правом блоке. Но спасибо за подсказку.
И этот код нужно поставить вместо стандартного яндексовского?
Денис Усманов
16 апреля 2024, 21:24
+1
Если правильно помню, этот скрипт подгружает карту при скролле после загрузки, если карта (как правило) внизу, то будет работать как надо.

<script>
    let ok = false;
    window.addEventListener('scroll', function() {
        if (ok === false) {
            ok = true;
            setTimeout(()=>{
                let mapScript = document.createElement('script');
                mapScript.src = 'https://api-maps.yandex.ru/services/constructor/1.0/js/?um=constructor%3A55fa9cd5f69ce35aa1eabe9bdf02db7fce18bb55c2ae44e2745b1b8b6cee9464&width=100%25&height=577&lang=ru_RU&scroll=true';
                document.getElementById('map').replaceWith(mapScript);
            }
            , 1000)
        }
    });
</script>

Где mapScript.src = '... это подключение скрипта Яндекс.Карты.
Где document.getElementById('map')… — это id элемента, в который надо загрузить карту.
Артур Шевченко
16 апреля 2024, 20:24
2
+2
Если на fenom то как-то так наверное
{set $cats = []}
{foreach $products as $product}
    {set $parent = $product.id | resource: 'parent'}
   {set $productsByCategory[$parent][] = $product}
{/foreach}
{foreach $productsByCategory as $parent => $products}
    {$parent | resource: 'pagetitle'}
    {foreach $products as $product}
       {$product | print}
    {/foreach}
{/foreach}
Дима Касаткин
16 апреля 2024, 17:44
0
Вам бы, коллеги, скооперироваться чтобы список ботов (user agent-ов) общий использовать для botAim и SmartSessions)

Предлагаю, если нужно, захостить его там же, где статистика установки компонентов, в надёжной инфраструктуре одного из крупных ДЦ. Я поспособствую!

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

С каждым годом всё больше и больше проблем от ботов. Ваши решения (Алексея и Андрея) очень помогают, и необходимость в них только растёт!
Наумов Алексей
16 апреля 2024, 14:37
+1
Перенесу и свой ответ тогда уж!:
пару месяцев назад я переписал это всё… сейчас по другому, в github код доступен. Можно даже PR сделать!
Интересная мысль насчет целесообразности создания сессий для ботов… в принципе может они и не нужны… как вариант можно добавить соответствующую настройку в компонент. В общем мысль сохранил.
Wassi Wassinen
16 апреля 2024, 11:37
0
<script>
document.addEventListener('fetchit:success', (e) => { // Добавляем listener на событие успешной обработки формы
    const { form } = e.detail; // Получаем форму

    switch (form.getAttribute('id')) {
        case 'form-1':
            // Обрабатываем только форму с id="form-1"
            // Тут код с отправкой целей
            break;
        case 'form-2':
            // Обрабатываем только форму с id="form-2"
            // Тут код с отправкой целей
            break;
    }
})
</script>

Я могу это так вставить на страницу с формами?
Баха Волков
16 апреля 2024, 11:07
0
А вообще есть бесплатный компонент ReachGoal в котором реализована интеграция с FetchIt
Баха Волков
16 апреля 2024, 11:05
+1
например так

document.addEventListener('fetchit:success', (e) => { // Добавляем listener на событие успешной обработки формы
    const { form } = e.detail; // Получаем форму

    switch (form.getAttribute('id')) {
        case 'form-1':
            // Обрабатываем только форму с id="form-1"
            // Тут код с отправкой целей
            break;
        case 'form-2':
            // Обрабатываем только форму с id="form-2"
            // Тут код с отправкой целей
            break;
    }
})