• Могу ли я выставить лицензию MIT в проекте, который использует библиотеку с лицензией Apache 2.0?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Да.

    https://www.apache.org/licenses/LICENSE-2.0
    2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

    4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    You must give any other recipients of the Work or Derivative Works a copy of this License; and
    You must cause any modified files to carry prominent notices stating that You changed the files; and
    You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
    If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
    Ответ написан
    1 комментарий
  • Как сделать event после выбора selected option?

    Mike_Ro
    @Mike_Ro Куратор тега JavaScript
    Python, JS, WordPress, SEO, Bots, Adversting
    change вместо click.

    жуквери:
    $('#USERS').change(function(e) {
        alert($(this).val());
    });

    vanilla:
    document.querySelector('#USERS').addEventListener('change', (e) => alert(e.target.value));
    Ответ написан
    2 комментария
  • Как в исходные файлы реакта попадает переменная __DEV__?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Переменная __DEV__ в исходных кодах React используется для определения режима сборки: разработка или продакшн. Это позволяет добавлять или исключать определенный код в зависимости от режима, что может быть полезно для добавления дополнительных предупреждений, проверок и другого кода, который полезен только во время разработки.

    На практике __DEV__ не определяется непосредственно в исходных файлах React. Вместо этого, она обычно заменяется на этапе сборки с помощью инструментов, таких как Webpack или Babel.

    Вот как это обычно работает:

    1. В исходном коде React, вы можете увидеть конструкции вроде:
    if (__DEV__) {
      console.warn('Some warning message');
    }

    2. Когда React собирается для режима разработки, __DEV__ заменяется на true, а для режима продакшн - на false.

    3. Инструменты сборки, такие как UglifyJS или Terser, затем оптимизируют этот код, удаляя условные блоки, которые никогда не выполняются. Например, если __DEV__ заменяется на false, то весь блок if (__DEV__) { ... } будет удален при минификации.

    Для того чтобы замена __DEV__ работала, вы обычно настраиваете ваш инструмент сборки (например, Webpack) с помощью плагинов, таких как DefinePlugin для Webpack, который заменяет определенные токены в исходном коде на заданные значения.

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

    На правах копипаста, самому в лом писать...
    Ответ написан
    1 комментарий
  • Как правильно настроить htaccess под ПС?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    У меня есть сайт, на котором появляются товары, под каждый товар создаётся страница.

    Правильно.
    Через определенное время, этот товар может быть удалён, а поисковый робот эту страницу уже просканирует и при повторном посещении в Вебмастере и в Гугл Консоли будут ошибки о несуществующих страницах.

    Как правильно настроить этот момент для SEO, чтобы не было проблем с поисковой оптимизацией ?

    Если Вы планируете позже продолжить продавать товар, то не удаляйте страницу. У Вас проиндексированная страница на которую было затрачено определенное количество времени на рост в ПС, а Вы ее удаляете... Пометьте товар "временно закончился, скоро появится" и предложите уведомить посетителя о возобновление продаж, таким образом Вы:
    - Сохраните поисковый трафик на эту страницу.
    - Есть определенный шанс, что пришедшие на эту страницу посетители - купят другой товар в Вашем магазине.
    - Есть определенный шанс заполучить контактные данные посетителя (уведомление о поступление товара в продажу), а затем попробовать продать ему уже другой товар.

    Если же, Вы не собираетесь возобновлять продажи товара, то никакие редиректы на 404 страницу делать не нужно, необходимо сразу отдавать удобную страницу с 404 кодом ответа. Под "удобной" я понимаю такую страницу, которая позволит человеку найти другой похожий товар и решить его задачу в рамках этой страницы, без лишних кликов.
    Ответ написан
    Комментировать
  • Как создать пункт меню и страницу в админке Wordpres через плагин?

    Mike_Ro
    @Mike_Ro Куратор тега WordPress
    Python, JS, WordPress, SEO, Bots, Adversting
    Создаем плагин, wp-content/plugins/best-plugin/best-plugin.php:
    <?php
    /**
     * Plugin Name: Чумовой плагин
     * Description: Это плагин, твердо и четко!
     */
    
    if(!defined('ABSPATH')) {
      exit;
    }
    
    class Best_Plugin {
      protected $menu_slug = 'best-plugin';
    
      public function __construct() {
        // добавление страницы с пунктом меню
        add_action('admin_menu', [$this, 'add_admin_page']);
    
        // добавление ссылки на настройки плагина в списке плагинов
        add_filter(
          'plugin_action_links_' . plugin_basename(__FILE__),
          [$this, 'add_settings_link']
        );
      }
    
      // страница, любое содержимое страницы, обычно это винегрет из html/js/php
      public function add_page() {}
    
      // добавление страницы с пунктом меню
      public function add_admin_page() {
        add_options_page(
          'Страница чумового плагина',
          'Чумовой плагин',
          'manage_options',
          $this->menu_slug,
          [$this, 'add_page'],
          1
        );
      }
    
      // добавление ссылки на настройки в списке плагинов
      public function add_settings_link($links) {
        $settings_link = "<a href=\"options-general.php?page={$this->menu_slug}\">Настройки чумового плагина</a>";
        array_unshift($links, $settings_link);
        return $links;
      }
    }
    
    new Best_Plugin();
    Ответ написан
    Комментировать
  • Как в PM2 задать автоматическую перезагрузку python скрипта при ошибке?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    https://pm2.io/docs/runtime/features/restart-strat...
    https://pm2.keymetrics.io/docs/usage/pm2-doc-singl...

    $ pm2 start app.py --name "app-name" --interpreter python3 --restart-delay 1000 --max-restarts 10
    $ pm2 save
    $ pm2 startup
    Ответ написан
    Комментировать
  • Как сделать фильтрацию столбика таблицы с чекбоксами?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    import React, {useState, useEffect} from 'react';
    
    function SuperComponent() {
        // хранилище для пунктов
        const [checkedLanguages, setCheckedLanguages] = useState([]);
        const [displayData, setDisplayData] = useState([]);
    
        const languagesData = [
            { id: "1", name: "Javascript" },
            { id: "2", name: "Python" },
            { id: "3", name: "Java" },
            { id: "4", name: "Kotlin" },
            { id: "5", name: "Dart" },
            { id: "6", name: "C#" }
        ];
    
        // фильтруем пункты
        useEffect(() => {
            if (checkedLanguages.length > 0) {
                const newData = languagesData.filter(language => checkedLanguages.includes(language.name));
                setDisplayData(newData);
            } else {
                setDisplayData(languagesData);
            }
        }, [checkedLanguages]);
    
        function handleCheckboxChange(event) {
            const languageName = event.target.value;
            if (event.target.checked) {
                setCheckedLanguages([...checkedLanguages, languageName]);
            } else {
                const newCheckedLanguages = checkedLanguages.filter(language => language !== languageName);
                setCheckedLanguages(newCheckedLanguages);
            }
        }
    
        return (
            <div>
                {checkedLanguages.map(language => (
                    <div key={language} className="selected-language">
                        <p>{language}</p>
                    </div>
                ))}
    
                {languagesData.map(language => (
                    <div key={language.id} className="checkbox-wrapper">
                        <input
                            type="checkbox"
                            value={language.name}
                            onChange={handleCheckboxChange}
                        />
                        <label>{language.name}</label>
                    </div>
                ))}
    
                // отображаем отфильтрованные пункты
                <div className="languages-list">
                    {displayData.map(language => (
                        <div key={language.id}>
                            {language.name}
                        </div>
                    ))}
                </div>
            </div>
        );
    }
    
    export default SuperComponent;
    Ответ написан
    1 комментарий
  • Как спарсить комментарии под постом вк на Python?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Да и по остальным моментам опыта и знаний 0

    Здесь есть 2 варианта:
    1. Использовать родной api ВК.
    2. Использовать сторонний фреймворк для тестирования веб-приложений. Но, учитывая, что знаний у вас 0, то используйте п1.

    https://vk.com/dev, заюзаем метод wall.getComments.

    Получение комментов из поста:
    import requests
    
    TOKEN = 'token'
    OWNER_ID = 'user_or_group_id'
    POST_ID = 'post_id'
    
    res = requests.get(
        'https://api.vk.com/method/wall.getComments',
        params = {
            'owner_id': OWNER_ID,
            'post_id': POST_ID,
            'access_token': TOKEN,
            'v': '5.130'
        }
    )
    
    comments = res.json()


    спарсить комментарии со всех постов
    сложить в один файл, преобразовав в вид ссылки
    удалить дубликаты
    рандомно выбрать 1 победителя, среди комментариев
    парсить по ключевому слову "участвую"
    что бы программа сама открыла ссылку победителя и отправила сообщение мол "вы победили"

    Комменты у Вас получены, осталось 5 шагов из 6, дерзайте!
    Ответ написан
    2 комментария
  • Как получить элемент по селектору из переменной?

    Mike_Ro
    @Mike_Ro Куратор тега JavaScript
    Python, JS, WordPress, SEO, Bots, Adversting
    jquery:
    const currentSlide = swp.slides[activeIndex]
    const btn = $(currentSlide).find('.header-banner-swiper__slide-btn');

    vanilla:
    const currentSlide = swp.slides[activeIndex]
    const btn = currentSlide.querySelector('.header-banner-swiper__slide-btn');
    Ответ написан
    Комментировать
  • Как обойти блокировку сайта от ботов для его парсинга в Screaming Frog?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Какие есть ещё способы обхода блокировки?

    - Ip из базы.
    - Количество визитов с одного ip за промежуток времени.
    - Проверка на безголовый браузер.
    - Быстрая базовая проверка на всякие популярные фреймворки для тестов (selenium, puppeteer итп).
    - Проверка на отпечаток устройства, в основном - на железо.
    - Если с парсим от лица сенсорного устройства - проверка атрибуты сенсорного устройства.
    Ответ написан
    Комментировать
  • Бесплатный онлайн-чат для сайта на JS?

    Mike_Ro
    @Mike_Ro Куратор тега JavaScript
    Python, JS, WordPress, SEO, Bots, Adversting
    https://www.chatwoot.com/
    https://github.com/chatwoot/chatwoot

    Self-hosted, десктоп/мобильное приложение, интеграции, боты, бесплатно!
    Ответ написан
    9 комментариев
  • Возможно ли из класса-потомка получить класс-родитель?

    Mike_Ro
    @Mike_Ro Куратор тега Python
    Python, JS, WordPress, SEO, Bots, Adversting
    Возможно ли из класса-потомка получить класс-родитель?

    Возможно, но все равно потребуется передавать атрибуты от потомка к родителю:
    from dataclasses import dataclass
    import typing
    import io
    
    # Определение базового класса для хранения информации о файле и ID объекта
    @dataclass
    class EjectedObjectDataFileNameAndObjectID:
        file_name: str  # Имя файла
        object_id: int  # ID объекта
    
    # Определение класса для хранения изображений
    @dataclass
    class EjectedObjectDataImages:
        images: typing.List[io.BytesIO]  # Список изображений в формате BytesIO
    
    # Класс, наследующий оба вышеуказанных класса и добавляющий дополнительные атрибуты
    @dataclass
    class EjectedObjectData(EjectedObjectDataImages, EjectedObjectDataFileNameAndObjectID):
        uuid: str  # Уникальный идентификатор
        position: typing.Tuple[int, int] = (0, 0)  # Позиция объекта (по умолчанию (0, 0))
        sorted: bool = False  # Флаг, указывающий, отсортирован ли объект (по умолчанию False)
    
        # Метод для создания экземпляра родительского класса из текущего экземпляра
        def to_parent(self) -> EjectedObjectDataFileNameAndObjectID:
            # Возвращаем новый экземпляр EjectedObjectDataFileNameAndObjectID,
            # используя атрибуты текущего экземпляра
            return EjectedObjectDataFileNameAndObjectID(self.file_name, self.object_id)
    
    
    # Пример использования:
    
    # Создаем экземпляр EjectedObjectData
    data = EjectedObjectData(["image1", "image2"], "some_file", 123, "some_uuid")
    
    # Получаем экземпляр родительского класса из экземпляра потомка
    parent_data = data.to_parent()
    
    # Выводим информацию о родительском классе
    print(parent_data)
    Ответ написан
  • Как реализовать пролистывание блока при прокрутке с учётом скролла страницы?

    Mike_Ro
    @Mike_Ro Куратор тега JavaScript
    Python, JS, WordPress, SEO, Bots, Adversting
    Я не знаю с какой стороны уже подступиться и как делать такой эффект. Я пробовал вешать position: sticky на блок и определять высоту родительского блока. Но это работает при медленном скролле, при быстром блок пролетает не успевая закончить слайдер.

    JS, если грубо описать последовательность действий, то:
    - Получаем контейнер со скроллом.
    - Создаем переменную со значением скролла контейнера.
    - Слушаем скролл контейнера, при изменение скролла - пишем значение в переменную.
    - Каждому элементу контейнера, которому необходимо "двигаться" при изменения скролла контейнера - прокидываем callback, который будет выполняться, если переменная со значением скролла контейнера изменилась.
    - Callback отправляет каждый элемент с "движением" из этого контейнера, который уже самостоятельно определяет, как он будет реагировать на каждое изменение переменной.

    Если Вы не готовы тратить время на велосипедо-строение и его поддержку, то лучше использовать чужое велосипедо-строение:
    https://greensock.com/scrolltrigger
    https://locomotivemtl.github.io/locomotive-scroll/
    Ответ написан
    2 комментария
  • В каких IT профессиях джуну можно работать на удалёнке или фрилансе?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Но всё оказалось не так как я предполагал и многие пишут, что джуны-программисты должны работать в офисе.

    Сразу, как их туда возьмут, а так они и в офисе не нужны, а Вы про удалёнку спрашиваете...
    Может всё-таки можно найти удалённую работу в разработке ну или хотя бы в принципе в IT за более менее человеческую плату

    За бесплатно - вероятность больше ноля, это не шутка.
    Ответ написан
    Комментировать
  • Почему react не присваивает ключи?

    Mike_Ro
    @Mike_Ro Куратор тега JavaScript
    Python, JS, WordPress, SEO, Bots, Adversting
    Each child in a list should have a unique "key" prop

    https://react.dev/learn/rendering-lists#keeping-li...

    // ..
    
    {items.map((i) => (
      <React.Fragment key={i.id}>
        <Item {...i}/>
      </React.Fragment>
    ))}
    
    // ..

    или
    // ..
    
    {items.map((i) => (
      <Item key={i.id} {...i}/>
    ))}
    
    // ..
    Ответ написан
  • Региональные субдомены: как все сделать правильно с точки зрения SEO?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Содержимое сайтов будет практически одинаковым (каталог, цены).

    Если не изменять контент, то вероятность склейки страниц с основным зеркалом приближается к 100%.

    Фактически, единственный вариант - изменять контент, чтобы общий процент дубликата уменьшался. Как изменять? - я бы делал это автоматически, в БД хранил данные, которые не требуют гео-привязки, а при рендере страницы - подставлял необходимые гео-ключи.

    UPD: автор обновил вопрос, значит пора обновить ответ!

    Как пример, есть сайты:
    spb.vorota-group.ru
    vorota-group.ru
    Они отлично ранжируются в своих регионах. Как мне сделать так же? Я в замешательстве.

    Анализ: (геолокацию явно не передаем).
    https://vorota-group.ru/rolstavni/, ключ "рольставни в москве":
    - Title - "Рольставни — купить в Москве по цене от 6000 руб. роллеты от производителя: заказать установку".
    - Description - "Заказать рольставни в Москве и области. Широкий выбор роллетов от производителей: Alutech, DoorHan, Hormann. Бесплатный выезд замерщика, гарантия, качественная продукция. Заказать готовые рольставни жалюзи можно по телефону: 8 (495) 845 03 35".
    - Ближайший текст -"Ворота и рольставни в Москве и Московской области".
    - Ключ с вариацией слова "Москва" встречается 6 раз.
    - Контакты с привязкой - "г. Москва, Тихорецкий б-р, д. 1".
    https://spb.vorota-group.ru/rolstavni/, "рольставни в санкт перетрубрг":
    - Title - "Рольставни — купить в Санкт-Петербурге по цене от 6000 руб. роллеты от производителя: заказать установку".
    - Description - "Заказать рольставни в Санкт-Петербурге и области. Широкий выбор роллетов от производителей: Alutech, DoorHan, Hormann. Бесплатный выезд замерщика, гарантия, качественная продукция. Заказать готовые рольставни жалюзи можно по телефону: +7 (812) 502 74 02".
    - Ближайший текст "Ворота и рольставни в Москве и Московской области".
    - Ключ с вариацией слова "Петербург" встречается 6 раз.
    - Контакты с привязкой - "г. Санкт-Петербург, Лиговский пр., 30А".

    Вывод 1. Хотим хорошего ранжирования в определенном регионе? - делайте уникальный контент под этот регион для всех страниц. Каждый процент НЕ уникальности контента на всем сайте в целом - увеличивает процент вероятности теневого бана сайт.
    Вывод 2. Для гугла этот сайт не сильно котируется, соответственно необходимо производить анализ ВСЕХ первых 10-20 сайтов конкурентов из ПС гугла, выявлять взаимосвязь и применять полученные сведения, но без ущерба для яндекса
    Ответ написан
    Комментировать
  • Может тег h2 идти сразу после h1 без разбивки текстом?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Может ли метатег h2 идти сразу после h1?

    Законом не запрещено. Если Вы имеете ввиду seo оптимизацию, то не рекомендую, т.к. если ключ не совпадает с titile, то поисковик попытается найти ключ в ближайшем заголовке, если ключ в заголовке найден, то затем, поисковик попытается найти ближайший (относительно найденного заголовка) сниппет с аналогичным ключом.

    Соответственно, если Вы хотите прогнозируемый сниппет в органике, то лучше вставлять описание (с ключом из заголовка) параграфом под заголовок.
    Ответ написан
    1 комментарий
  • Как проверить правильность hreflang?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    - Google Search Console > International Targeting > Ошибки в hreflang.
    - Google "hreflang checker" > https://hreflangchecker.com/ .
    Ответ написан
    Комментировать