Top.Mail.Ru

Свежие статьи

Рубрики

Рубрика: Блог разработчика

Блог разработчика-самоучки: создаю сайты и плагины для WordPress с помощью ИИ. Делюсь кодом, ошибками и готовыми решениями на Python и PHP.

  • Как я увлёкся программированием и забыл о SEO: история ручной настройки сайта без плагинов

    Как я увлёкся программированием и забыл о SEO: история ручной настройки сайта без плагинов

    Последние месяцы я жил в режиме непрерывного кодинга. Плагин для ВК, Python-скрипты, ревью в WordPress.org — и вот однажды я заглянул в Яндекс. Вебмастер и понял, что моего сайта там нет. Совсем.

    milyutin-codes.ru не индексировался. Ни одной страницы в поиске. Блог, в который я вложил месяцы работы, был невидим.

    И это стало отправной точкой для новой эпопеи. Я решил отказаться от SEO-плагинов и написать всё вручную. Если уж я пишу код, то пусть он будет полностью моим.

    Как я увлёкся и что упустил

    Всё началось с того, что я погрузился в разработку. Каждый день я что-то писал: то плагин для ВК, то Python-скрипт для автопостинга, то пытался починить очередной баг. Мне нравилось создавать. Мне нравилось решать задачи. Мне нравилось чувствовать себя разработчиком.

    Но в этой гонке я перестал думать о том, для чего всё это делается. Я создавал статьи, публиковал их, но не задумывался: а увидят ли их люди? Найдут ли их поисковые системы? Будут ли они приносить трафик?

    Ответ был неутешительным. Нет. Не найдут. Не будут.

    Я запустил поиск по своему сайту в Яндексе и Google. Ноль результатов. Сайт не индексировался. Мой блог, в который я вложил столько сил, был невидим для поисковиков.

    Забыл о SEO: ручная настройка WordPress без плагинов
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Это был удар. Я осознал, что всё это время строил дом без фундамента. Красивый, с хорошей отделкой, но без фундамента.

    Решение: отказаться от SEO-плагинов

    SEO-плагин
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Когда я понял масштаб проблемы, первая мысль была: «Поставлю Yoast SEO или Rank Math, и всё наладится». Это логично. Тысячи сайтов используют эти плагины. Они генерируют sitemap, настраивают мета-теги, добавляют Schema.org, управляют robots.txt.

    Но я остановился. Потому что вспомнил, зачем я вообще начал этот путь.

    Я начал его, чтобы учиться. Чтобы понимать, как всё работает изнутри. Чтобы не зависеть от готовых решений, которые я не контролирую.

    И я принял решение: никаких SEO-плагинов. Всё вручную.

    Это было сложнее. Это заняло больше времени. Но это дало мне полный контроль. И, что важнее, понимание.

    Борьба с кодом: как я настраивал SEO вручную

    Борьба с кодом
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я начал с создания дочерней темы для Twenty Twenty-Five. Это базовый шаг, который позволяет вносить изменения, не трогая родительскую тему. Я создал папку `twentytwentyfive-child`, файлы `style.css` и `functions.php`.

    Дальше началась настоящая работа.

    Мета-теги и заголовки

    Я добавил в `functions.php` код, который:
    — Позволяет задавать SEO-заголовок и SEO-описание для каждого поста через мета-боксы.
    — Автоматически формирует заголовок страницы через фильтр `pre_get_document_title`.
    — Выводит мета-тег description в `<head>`.

    Это было непросто. Пришлось разбираться с nonce, санитизацией и экранированием. Но я справился.

    Robots.txt

    Я создал файл `robots.txt` в корне сайта. Он закрывает служебные разделы (`/wp-admin/`, `/wp-includes/`), но открывает рубрики (`/category/`) для индексации.

    Это был важный шаг. Раньше я закрывал всё подряд, не понимая, что лишаю свой сайт трафика.

    **Управление индексацией архивов**

    Я добавил мета-тег `noindex, follow` для всех архивных страниц: рубрик, меток, дат, авторов. Это позволяет не плодить дубли и сконцентрировать вес на постах.

    Open Graph и Twitter Cards

    Я добавил код, который автоматически генерирует теги Open Graph и Twitter Cards для каждой страницы. Теперь, когда кто-то делится ссылкой на мою статью в Telegram или ВКонтакте, там отображается красивое превью с заголовком, описанием и картинкой.

    Schema.org

    Я добавил JSON-LD разметку для статей (тип BlogPosting) и для страницы блога (тип Blog). Это помогает поисковикам лучше понимать, что на странице — статья или архив.

    Sitemap

    Я создал XML-карту сайта. Правда, с ней были проблемы: сначала она была недоступна, потом все даты `lastmod` были одинаковыми. Но я исправил это.

    Многократные итерации: как я проверял и перепроверял

    Многократные итерации
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я не могу сказать, что всё получилось с первого раза. Это было далеко не так.

    Я обращался к DeepSeek за помощью. Мы вместе анализировали код, искали ошибки, проверяли результаты. И каждый раз DeepSeek находил что-то новое.

    Сначала он сказал, что sitemap недоступен. Я исправил.

    Потом — что Open Graph на странице блога дублирует главную. Я исправил.

    Потом — что Schema.org на странице блога описывает конкретную статью, а не архив. Я исправил.

    Потом — что на странице блога нет статических ссылок на статьи. И вот тут мы застряли.

    Это была самая сложная проблема. Страница `/blog/` загружала список статей через JavaScript. В HTML-коде не было ни одной ссылки на статьи. Для поискового робота это выглядело так, будто на странице нет контента.

    DeepSeek предложил решение: вывести список статей через `WP_Query` или `get_posts()` прямо в шаблоне. Я попробовал. И это сработало.

    Что в итоге получилось

    Что в итоге получилось
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Сегодня мой сайт — это полноценная SEO-система, написанная вручную, без единого плагина.

    Что работает:
    — ✅ Мета-теги, Open Graph, Twitter Cards — уникальны для каждой страницы.
    — ✅ Schema.org разметка — для статей и архивов.
    — ✅ Robots.txt — открывает рубрики, закрывает служебные разделы.
    — ✅ Sitemap.xml — содержит список всех страниц с корректными датами.
    — ✅ Canonical — для каждой страницы.
    — ✅ Статические ссылки на статьи — в HTML-коде страницы блога.
    — ✅ Управление индексацией архивов — через мета-теги.

    Что ещё требует доработки:
    — ⚠️ Sitemap иногда недоступен из-за особенностей хостинга. Работаю над этим.
    — ⚠️ Индексация пока нулевая. Но это вопрос времени — сайт молодой, и поисковики не торопятся.
    — ⚠️ Некоторые теги закрыты от индексации. Но это осознанное решение.

    Что я понял за это время

    1. Увлечение — это хорошо, но нельзя забывать о фундаменте.

    Я так увлёкся программированием, что забыл: сайт — это не только код. Это ещё и контент, который должен быть найден. SEO — это фундамент, без которого всё остальное теряет смысл.

    2. Плагины — это не всегда решение.

    Я отказался от SEO-плагинов и не жалею. Да, было сложнее. Да, пришлось разбираться во многом. Но теперь я понимаю, как всё работает. И могу контролировать каждый аспект.

    3. DeepSeek — это не просто помощник.

    Он помог мне не только с кодом, но и с пониманием того, что я упустил. Иногда лучший совет — это не «как сделать», а «на что обратить внимание».

    4. Многократные итерации — это нормально.

    Я проверял сайт раз за разом. Каждый раз находились новые ошибки. Это не провал. Это процесс. Главное — не останавливаться.

    5. Индексация — это не мгновенный процесс.

    Мой сайт до сих пор не в индексе. Но это не значит, что я делаю что-то не так. Это значит, что поисковики ещё не обошли его. Я продолжаю работать, отправляю sitemap в Вебмастер и GSC, публикую контент. И верю, что результат придёт.

    Что дальше?

    Продолжение следует
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я продолжу улучшать SEO своего сайта. В планах:
    — Добиться стабильной доступности sitemap.
    — Настроить разные `lastmod` для каждой страницы.
    — Добавить внутреннюю перелинковку (блок «Читайте также»).
    — Улучшить скорость загрузки.

    А главное — продолжать публиковать контент. Потому что SEO = 20% техники + 80% контента. Техническая часть у меня почти идеальная. Теперь важно наполнять сайт полезными материалами.

    Если ты тоже увлёкся программированием и забыл о SEO — остановись на минуту. Проверь свой сайт. Посмотри, индексируется ли он. Есть ли у тебя sitemap. Правильно ли настроен robots.txt.

    Это не так сложно, как кажется. Да, придётся разобраться. Да, будет не с первого раза. Но это стоит того. Потому что сайт, который не находят люди, — это сайт, который не существует.

    Подписывайся на мой блог, чтобы следить за моим путём. Вместе мы строим полезные инструменты и учимся делать всё правильно.

    Контакты

    📧 Email: milyutinkv@gmail.com
    🌐 Сайт: milyutin-codes.ru
    💬 Группа ВК: vk.com/milyutin_codes

    Задавай вопросы, делись идеями, тестируй плагины. Вместе мы строим полезные инструменты!

    Продолжение следует. Сайт индексируется, плагины работают, SEO настроено вручную.

    Константин Милютин
    Автор блога «Милютин Код»

  • Отказ от SEO-плагинов и переход на собственное SEO в WordPress

    Отказ от SEO-плагинов и переход на собственное SEO в WordPress

    Я давно присматривался к SEO-плагинам: Yoast, Rank Math, All in One SEO. Удобно, красиво, но есть проблема — в бесплатных версиях они ограничивают возможности. А покупать PRO-версии или ставить ломаные — не мой путь. Я хочу контролировать каждый тег, каждую мету, каждую строчку кода. И я решил: сделаю всё сам, вручную, через дочернюю тему.

    Это оказалось не так страшно, как звучит. Да, пришлось разбираться с хуками, фильтрами, nonce и экранированием. Но зато теперь я точно знаю, как работает SEO на моём сайте. И могу менять что угодно без оглядки на разработчиков плагинов.

    Сегодня расскажу, как я это сделал. По шагам. С кодом, который можно сразу скопировать и использовать.

    Создание дочерней темы

    Что такое дочерняя тема и зачем она нужна?

    Дочерняя тема — это тема-наследница. Она берёт все стили и шаблоны от родительской темы, но позволяет добавлять свой код без риска потерять изменения при обновлении родительской темы. Я вношу все изменения ТОЛЬКО в дочернюю тему.

    Шаг 1. Создаю папку для дочерней темы

    Через FTP или файловый менеджер хостинга я перешёл в папку:

    text
    /wp-content/themes/

    Создал новую папку с именем:

    text
    название-родительской-темы-child

    Пример: для темы Twenty Twenty-Five папка называется twentytwentyfive-child.

    Шаг 2. Создаю файл style.css

    Внутри папки дочерней темы создал файл style.css со следующим содержимым:

    css
    /*
    Theme Name: Название вашей дочерней темы
    Template: название-родительской-темы
    Description: Дочерняя тема для [Название родительской темы], созданная для ручного SEO
    Author: Ваше имя
    Version: 1.0
    */
    
    /* Импорт стилей родительской темы */
    @import url("../название-родительской-темы/style.css");
    
    /* Здесь потом будем добавлять свои стили (если понадобятся) */

    Пояснение:

    • Theme Name — название, которое увидите в админке WordPress.

    • Template — ОБЯЗАТЕЛЬНО должно совпадать с именем папки родительской темы (например, twentytwentyfive).

    • @import — подключает все стили родительской темы, чтобы внешний вид не сломался.

    Шаг 3. Создаю файл functions.php

    В той же папке создал файл functions.php:

    php
    <?php
    /**
     * Функции дочерней темы
     * Подключаем стили родителя и дочерние стили (если появятся)
     */
    function child_enqueue_styles() {
        // Регистрируем стиль родительской темы
        wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
    }
    add_action( 'wp_enqueue_scripts', 'child_enqueue_styles' );

    Пояснение: этот файл говорит WordPress загружать стили родительской темы правильным способом (более надёжно, чем @import в CSS).

    Шаг 4. Активирую дочернюю тему

    Зашёл в админку WordPress → «Внешний вид» → «Темы».

    Нашёл свою дочернюю тему и нажал «Активировать».

    Сайт выглядит так же, как и раньше.

    Базовые SEO-настройки (файл functions.php)

    ВСЕ ДАЛЬНЕЙШИЕ ИЗМЕНЕНИЯ вносятся в файл functions.php дочерней темы. Я открыл его и добавлял каждый следующий блок кода в конец файла (перед закрывающим ?> если он есть, или просто в конец).

    Блок 1. Управление заголовками (Title) и мета-описаниями (Description)

    Этот код добавляет на страницу редактирования каждого поста два новых поля: «SEO-заголовок» и «SEO-описание». Если заполнить эти поля, они будут использованы в заголовке страницы и в мета-теге description. Если поля пустые — заголовок строится автоматически, а описание генерируется из контента.

    php
    // ========== НАЧАЛО БЛОКА: заголовки и описания ==========
    
    /**
     * 1. Добавляем мета-боксы для SEO-заголовка и SEO-описания
     */
    function seo_add_meta_boxes() {
        add_meta_box(
            'seo_meta_box',
            'SEO-настройки',
            'seo_meta_box_html',
            'post',
            'normal',
            'high'
        );
    }
    add_action( 'add_meta_boxes', 'seo_add_meta_boxes' );
    
    /**
     * 2. Выводим HTML-поля внутри мета-бокса
     */
    function seo_meta_box_html( $post ) {
        $seo_title = get_post_meta( $post->ID, '_seo_title', true );
        $seo_desc   = get_post_meta( $post->ID, '_seo_description', true );
        
        wp_nonce_field( 'seo_save_meta_box_data', 'seo_meta_box_nonce' );
        
        echo '<p><label for="seo_title_field">SEO-заголовок (Title):</label><br>';
        echo '<input type="text" id="seo_title_field" name="seo_title_field" value="' . esc_attr( $seo_title ) . '" size="70" placeholder="Введите заголовок для SEO (до 60 символов)" /></p>';
        
        echo '<p><label for="seo_description_field">SEO-описание (Description):</label><br>';
        echo '<textarea id="seo_description_field" name="seo_description_field" rows="3" cols="70" placeholder="Введите описание для SEO (до 160 символов)">' . esc_textarea( $seo_desc ) . '</textarea></p>';
    }
    
    /**
     * 3. Сохраняем данные при сохранении поста
     */
    function seo_save_meta_box_data( $post_id ) {
        if ( ! isset( $_POST['seo_meta_box_nonce'] ) ||
             ! wp_verify_nonce( $_POST['seo_meta_box_nonce'], 'seo_save_meta_box_data' ) ) {
            return;
        }
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return;
        }
        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return;
        }
        if ( isset( $_POST['seo_title_field'] ) ) {
            update_post_meta( $post_id, '_seo_title', sanitize_text_field( $_POST['seo_title_field'] ) );
        }
        if ( isset( $_POST['seo_description_field'] ) ) {
            update_post_meta( $post_id, '_seo_description', sanitize_textarea_field( $_POST['seo_description_field'] ) );
        }
    }
    add_action( 'save_post', 'seo_save_meta_box_data' );
    
    /**
     * 4. Изменяем заголовок страницы (Title)
     */
    function seo_custom_title( $title ) {
        if ( is_singular() ) {
            $post_id = get_queried_object_id();
            $seo_title = get_post_meta( $post_id, '_seo_title', true );
            if ( ! empty( $seo_title ) ) {
                return $seo_title;
            }
        }
        return $title;
    }
    add_filter( 'pre_get_document_title', 'seo_custom_title', 10, 1 );
    
    /**
     * 5. Добавляем мета-тег description в <head>
     */
    function seo_add_description_meta() {
        if ( is_singular() ) {
            $post_id = get_queried_object_id();
            $seo_desc = get_post_meta( $post_id, '_seo_description', true );
            if ( ! empty( $seo_desc ) ) {
                echo '<meta name="description" content="' . esc_attr( $seo_desc ) . '" />' . "\n";
                return;
            }
            $post = get_post( $post_id );
            if ( $post ) {
                $content = strip_shortcodes( $post->post_content );
                $content = wp_strip_all_tags( $content );
                $content = trim( preg_replace( '/\s+/', ' ', $content ) );
                $excerpt = mb_substr( $content, 0, 160, 'UTF-8' );
                if ( ! empty( $excerpt ) ) {
                    echo '<meta name="description" content="' . esc_attr( $excerpt ) . '" />' . "\n";
                }
            }
        }
    }
    add_action( 'wp_head', 'seo_add_description_meta', 5 );
    
    // ========== КОНЕЦ БЛОКА ==========

    Что делает этот блок:

    • Добавляет поля «SEO-заголовок» и «SEO-описание» в редактор постов.

    • Сохраняет введённые значения в базу данных.

    • Подставляет их в <title> и <meta name="description">.

    • Если поля пустые — автоматически генерирует описание из первых 160 символов контента.

    Блок 2. Управление индексацией архивов

    Этот код добавляет на все архивные страницы (рубрики, метки, даты, авторские архивы) мета-тег noindex, follow, чтобы поисковики не индексировали эти страницы, но продолжали переходить по ссылкам.

    php
    // ========== НАЧАЛО БЛОКА: управление индексацией архивов ==========
    
    function seo_archive_noindex() {
        if ( is_archive() || is_tag() || is_category() || is_date() || is_author() ) {
            echo '<meta name="robots" content="noindex, follow" />' . "\n";
        }
        if ( is_paged() && ! is_singular() ) {
            echo '<meta name="robots" content="noindex, follow" />' . "\n";
        }
    }
    add_action( 'wp_head', 'seo_archive_noindex', 5 );
    
    // ========== КОНЕЦ БЛОКА ==========

    Что делает этот блок:

    • Закрывает от индексации все архивы (рубрики, метки, даты, авторов).

    • Закрывает от индексации страницы пагинации (кроме пагинации внутри постов).

    Блок 3. Канонические ссылки для пагинации

    php
    // ========== НАЧАЛО БЛОКА: канонические ссылки для пагинации ==========
    
    function seo_canonical_for_paged() {
        if ( is_paged() ) {
            $base_url = get_pagenum_link( 1 );
            echo '<link rel="canonical" href="' . esc_url( $base_url ) . '" />' . "\n";
        }
    }
    add_action( 'wp_head', 'seo_canonical_for_paged', 3 );
    
    // ========== КОНЕЦ БЛОКА ==========

    Что делает этот блок: Указывает поисковикам, что все страницы пагинации (например, /page/2/) — это вариант первой страницы, чтобы избежать дублей.

    Блок 4. Канонические ссылки без параметров

    Этот блок удаляет все GET-параметры из канонической ссылки (например, ?utm_source=...), чтобы поисковик всегда знал основную версию страницы.

    php
    // ========== НАЧАЛО БЛОКА: канонические ссылки без параметров ==========
    
    function seo_add_canonical_without_params() {
        $protocol = is_ssl() ? 'https://' : 'http://';
        $host = $_SERVER['HTTP_HOST'];
        $request_uri = $_SERVER['REQUEST_URI'];
        $path = strtok( $request_uri, '?' );
        $canonical_url = $protocol . $host . $path;
        $current_url = $protocol . $host . $request_uri;
        if ( $canonical_url !== $current_url ) {
            echo '<link rel="canonical" href="' . esc_url( $canonical_url ) . '" />' . "\n";
        }
    }
    add_action( 'wp_head', 'seo_add_canonical_without_params', 1 );
    
    // ========== КОНЕЦ БЛОКА ==========

    Что делает этот блок: Добавляет каноническую ссылку на чистый URL (без параметров) для всех страниц, к которым обращаются с параметрами в адресной строке.

    Open Graph и Twitter Cards

    Эти теги нужны для красивого отображения ссылок в социальных сетях и мессенджерах (Telegram, ВКонтакте, Facebook, Twitter и других).

    php
    // ========== НАЧАЛО БЛОКА: Open Graph и Twitter Cards ==========
    
    function seo_add_social_meta() {
        global $post;
    
        $site_name = get_bloginfo( 'name' );
        $site_description = get_bloginfo( 'description' );
        $default_image = ''; // Сюда можно вставить URL стандартной картинки
    
        $title = $site_name;
        $description = $site_description;
        $image = $default_image;
        $url = get_permalink();
        $type = 'website';
    
        if ( is_singular() ) {
            $post_id = get_queried_object_id();
            $url = get_permalink( $post_id );
            $type = 'article';
    
            $seo_title = get_post_meta( $post_id, '_seo_title', true );
            if ( ! empty( $seo_title ) ) {
                $title = $seo_title;
            } else {
                $title = get_the_title( $post_id ) . ' — ' . $site_name;
            }
    
            $seo_desc = get_post_meta( $post_id, '_seo_description', true );
            if ( ! empty( $seo_desc ) ) {
                $description = $seo_desc;
            } else {
                $content = strip_shortcodes( $post->post_content );
                $content = wp_strip_all_tags( $content );
                $content = trim( preg_replace( '/\s+/', ' ', $content ) );
                $description = mb_substr( $content, 0, 200, 'UTF-8' );
                if ( empty( $description ) ) {
                    $description = $site_description;
                }
            }
    
            if ( has_post_thumbnail( $post_id ) ) {
                $image = get_the_post_thumbnail_url( $post_id, 'full' );
            } else {
                $pattern = '/<img[^>]+src="([^">]+)"/';
                preg_match( $pattern, $post->post_content, $matches );
                if ( ! empty( $matches[1] ) ) {
                    $image = $matches[1];
                }
            }
        } elseif ( is_front_page() || is_home() ) {
            $title = $site_name;
            $description = $site_description;
            $url = home_url( '/' );
            $type = 'website';
        } else {
            $title = wp_get_document_title();
            $description = $site_description;
            $url = get_permalink();
            $type = 'website';
        }
    
        // РАСКОММЕНТИРУЙТЕ И УКАЖИТЕ СВОЙ URL, ЕСЛИ ХОТИТЕ СТАНДАРТНУЮ КАРТИНКУ-ЗАГЛУШКУ:
        // if ( empty( $image ) ) $image = 'https://ваш-сайт.ru/wp-content/uploads/logo.png';
    
        $title = esc_attr( $title );
        $description = esc_attr( $description );
        $image = esc_url( $image );
        $url = esc_url( $url );
    
        echo "\n<!-- Open Graph / SEO Meta -->\n";
        echo '<meta property="og:title" content="' . $title . '" />' . "\n";
        echo '<meta property="og:description" content="' . $description . '" />' . "\n";
        echo '<meta property="og:type" content="' . $type . '" />' . "\n";
        echo '<meta property="og:url" content="' . $url . '" />' . "\n";
        echo '<meta property="og:site_name" content="' . esc_attr( $site_name ) . '" />' . "\n";
        echo '<meta property="og:locale" content="' . get_locale() . '" />' . "\n";
    
        if ( ! empty( $image ) ) {
            echo '<meta property="og:image" content="' . $image . '" />' . "\n";
            echo '<meta property="og:image:width" content="1200" />' . "\n";
            echo '<meta property="og:image:height" content="630" />' . "\n";
        }
    
        echo "\n<!-- Twitter Card -->\n";
        echo '<meta name="twitter:card" content="summary_large_image" />' . "\n";
        echo '<meta name="twitter:title" content="' . $title . '" />' . "\n";
        echo '<meta name="twitter:description" content="' . $description . '" />' . "\n";
        if ( ! empty( $image ) ) {
            echo '<meta name="twitter:image" content="' . $image . '" />' . "\n";
        }
        // РАСКОММЕНТИРУЙТЕ, ЕСЛИ У ВАС ЕСТЬ АККАУНТ В TWITTER:
        // echo '<meta name="twitter:site" content="@ваш_аккаунт" />' . "\n";
    }
    add_action( 'wp_head', 'seo_add_social_meta', 3 );
    
    // ========== КОНЕЦ БЛОКА ==========

    Что делает этот блок:

    • Генерирует Open Graph-теги (og:title, og:description, og:image, og:url и др.) для соцсетей и мессенджеров.

    • Генерирует Twitter Cards для корректного отображения в Twitter/X.

    • Берёт данные из SEO-полей, если они заполнены, или генерирует автоматически.

    Schema-разметка (JSON-LD) для статей

    Schema-разметка помогает поисковым системам лучше понимать содержимое страницы: что это за статья, кто автор, когда опубликована, есть ли изображение.

    php
    // ========== НАЧАЛО БЛОКА: Schema-разметка JSON-LD ==========
    
    function seo_add_schema_org() {
        if ( ! is_singular() ) {
            return;
        }
    
        global $post;
        $post_id = $post->ID;
    
        $site_name = get_bloginfo( 'name' );
        $site_url = home_url( '/' );
        $post_title = get_the_title( $post_id );
        $post_url = get_permalink( $post_id );
        $post_date = get_the_date( 'c', $post_id );
        $post_modified = get_the_modified_date( 'c', $post_id );
        $author_name = get_the_author_meta( 'display_name', $post->post_author );
        $author_url = get_author_posts_url( $post->post_author );
    
        $image_url = '';
        if ( has_post_thumbnail( $post_id ) ) {
            $image_url = get_the_post_thumbnail_url( $post_id, 'full' );
        } else {
            $pattern = '/<img[^>]+src="([^">]+)"/';
            preg_match( $pattern, $post->post_content, $matches );
            if ( ! empty( $matches[1] ) ) {
                $image_url = $matches[1];
            }
        }
    
        $seo_desc = get_post_meta( $post_id, '_seo_description', true );
        if ( ! empty( $seo_desc ) ) {
            $description = $seo_desc;
        } else {
            $content = strip_shortcodes( $post->post_content );
            $content = wp_strip_all_tags( $content );
            $content = trim( preg_replace( '/\s+/', ' ', $content ) );
            $description = mb_substr( $content, 0, 200, 'UTF-8' );
        }
    
        $schema = array(
            '@context' => 'https://schema.org',
            '@type'    => 'Article',
            'headline' => $post_title,
            'description' => $description,
            'mainEntityOfPage' => array(
                '@type' => 'WebPage',
                '@id'   => $post_url,
            ),
            'datePublished' => $post_date,
            'dateModified'  => $post_modified,
            'author' => array(
                '@type' => 'Person',
                'name'  => $author_name,
                'url'   => $author_url,
            ),
            'publisher' => array(
                '@type' => 'Organization',
                'name'  => $site_name,
                'url'   => $site_url,
            ),
        );
    
        if ( ! empty( $image_url ) ) {
            $schema['image'] = array(
                '@type'  => 'ImageObject',
                'url'    => $image_url,
                'width'  => 1200,
                'height' => 630,
            );
        }
    
        echo "\n<!-- Schema.org JSON-LD -->\n";
        echo '<script type="application/ld+json">' . json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . '</script>' . "\n";
    }
    add_action( 'wp_head', 'seo_add_schema_org', 4 );
    
    // ========== КОНЕЦ БЛОКА ==========

    Что делает этот блок: Добавляет структурированные данные Schema.org для статей (тип Article) — это помогает поисковикам лучше понимать содержимое и может улучшить отображение в выдаче.

    Хлебные крошки (BreadcrumbList Schema)

    Этот блок добавляет микроразметку для хлебных крошек — цепочки навигации «Главная → Рубрика → Пост».

    php
    // ========== НАЧАЛО БЛОКА: хлебные крошки (BreadcrumbList) ==========
    
    function seo_add_breadcrumb_schema() {
        $breadcrumbs = array();
    
        $home_url = home_url( '/' );
        $home_title = get_bloginfo( 'name' );
        $breadcrumbs[] = array(
            '@type' => 'ListItem',
            'position' => 1,
            'name' => $home_title,
            'item' => $home_url,
        );
    
        if ( is_singular() ) {
            $post_id = get_queried_object_id();
            $post_type = get_post_type( $post_id );
    
            if ( $post_type == 'post' ) {
                $categories = get_the_category( $post_id );
                if ( ! empty( $categories ) ) {
                    $cat = $categories[0];
                    $cat_link = get_category_link( $cat->term_id );
                    $breadcrumbs[] = array(
                        '@type' => 'ListItem',
                        'position' => 2,
                        'name' => $cat->name,
                        'item' => $cat_link,
                    );
                }
                $breadcrumbs[] = array(
                    '@type' => 'ListItem',
                    'position' => count( $breadcrumbs ) + 1,
                    'name' => get_the_title( $post_id ),
                );
            } elseif ( $post_type == 'page' ) {
                $breadcrumbs[] = array(
                    '@type' => 'ListItem',
                    'position' => 2,
                    'name' => get_the_title( $post_id ),
                );
            } else {
                $breadcrumbs[] = array(
                    '@type' => 'ListItem',
                    'position' => 2,
                    'name' => get_the_title( $post_id ),
                );
            }
        } elseif ( is_category() ) {
            $cat_id = get_queried_object_id();
            $cat = get_category( $cat_id );
            $breadcrumbs[] = array(
                '@type' => 'ListItem',
                'position' => 2,
                'name' => $cat->name,
            );
        } elseif ( is_tag() ) {
            $tag_id = get_queried_object_id();
            $tag = get_tag( $tag_id );
            $breadcrumbs[] = array(
                '@type' => 'ListItem',
                'position' => 2,
                'name' => $tag->name,
            );
        } elseif ( is_author() ) {
            $author = get_queried_object();
            $breadcrumbs[] = array(
                '@type' => 'ListItem',
                'position' => 2,
                'name' => 'Автор: ' . $author->display_name,
            );
        } elseif ( is_date() ) {
            $breadcrumbs[] = array(
                '@type' => 'ListItem',
                'position' => 2,
                'name' => 'Архив дат',
            );
        } elseif ( is_search() ) {
            $breadcrumbs[] = array(
                '@type' => 'ListItem',
                'position' => 2,
                'name' => 'Результаты поиска: ' . get_search_query(),
            );
        } elseif ( is_404() ) {
            $breadcrumbs[] = array(
                '@type' => 'ListItem',
                'position' => 2,
                'name' => 'Страница не найдена',
            );
        }
    
        if ( count( $breadcrumbs ) > 1 ) {
            $schema = array(
                '@context' => 'https://schema.org',
                '@type' => 'BreadcrumbList',
                'itemListElement' => $breadcrumbs,
            );
            echo "\n<!-- Breadcrumb Schema -->\n";
            echo '<script type="application/ld+json">' . json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . '</script>' . "\n";
        }
    }
    add_action( 'wp_head', 'seo_add_breadcrumb_schema', 4 );
    
    // ========== КОНЕЦ БЛОКА ==========

    Что делает этот блок: Добавляет структурированные данные для хлебных крошек — это помогает поисковикам понять структуру сайта и может улучшить сниппеты в выдаче.

    XML-карта сайта (Sitemap)

    Этот код создаёт динамическую XML-карту сайта, доступную по адресу https://ваш-сайт.ru/sitemap.xml.

    php
    // ========== НАЧАЛО БЛОКА: XML-карта сайта ==========
    
    function seo_add_sitemap_rewrite() {
        add_rewrite_rule(
            '^sitemap\.xml$',
            'index.php?seo_sitemap=1',
            'top'
        );
    }
    add_action( 'init', 'seo_add_sitemap_rewrite' );
    
    function seo_add_sitemap_query_var( $vars ) {
        $vars[] = 'seo_sitemap';
        return $vars;
    }
    add_filter( 'query_vars', 'seo_add_sitemap_query_var' );
    
    function seo_sitemap_handler() {
        if ( get_query_var( 'seo_sitemap' ) != 1 ) {
            return;
        }
    
        header( 'Content-Type: application/xml; charset=utf-8' );
        header( 'X-Robots-Tag: noindex, follow' );
        header( 'Cache-Control: no-cache, must-revalidate' );
        header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' );
    
        echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
        echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
    
        // Главная страница
        $home_url = home_url( '/' );
        echo '<url>';
        echo '<loc>' . esc_url( $home_url ) . '</loc>';
        echo '<priority>1.0</priority>';
        echo '<changefreq>daily</changefreq>';
        echo '<lastmod>' . date( 'Y-m-d' ) . '</lastmod>';
        echo '</url>' . "\n";
    
        // Все опубликованные посты
        $posts = get_posts( array(
            'post_type'      => 'post',
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'orderby'        => 'modified',
            'order'          => 'DESC',
        ) );
    
        foreach ( $posts as $post ) {
            $url = get_permalink( $post->ID );
            $lastmod = get_the_modified_date( 'Y-m-d', $post->ID );
            echo '<url>';
            echo '<loc>' . esc_url( $url ) . '</loc>';
            echo '<priority>0.8</priority>';
            echo '<changefreq>weekly</changefreq>';
            echo '<lastmod>' . $lastmod . '</lastmod>';
            echo '</url>' . "\n";
        }
    
        // Все опубликованные страницы (Pages)
        $pages = get_pages( array(
            'post_status' => 'publish',
            'hierarchical' => 0,
        ) );
    
        foreach ( $pages as $page ) {
            if ( get_option( 'page_on_front' ) == $page->ID ) {
                continue;
            }
            $url = get_permalink( $page->ID );
            $lastmod = get_the_modified_date( 'Y-m-d', $page->ID );
            echo '<url>';
            echo '<loc>' . esc_url( $url ) . '</loc>';
            echo '<priority>0.6</priority>';
            echo '<changefreq>monthly</changefreq>';
            echo '<lastmod>' . $lastmod . '</lastmod>';
            echo '</url>' . "\n";
        }
    
        echo '</urlset>';
        exit;
    }
    add_action( 'template_redirect', 'seo_sitemap_handler' );
    
    // ========== КОНЕЦ БЛОКА ==========

    Что делает этот блок: Создаёт динамическую XML-карту сайта, которая автоматически обновляется при публикации новых постов. Включает главную страницу, все посты и все страницы (Pages).

    Важно: После добавления этого кода зайдите в админку → «Настройки» → «Постоянные ссылки» и нажмите «Сохранить изменения» — это обновит правила ЧПУ.

    Файл robots.txt

    Создайте в корневой папке сайта (там же, где лежат wp-config.php и wp-load.php) файл robots.txt со следующим содержимым:

    text
    User-agent: *
    Allow: /wp-content/uploads/
    Disallow: /wp-admin/
    Disallow: /wp-includes/
    Disallow: /wp-content/plugins/
    Disallow: /wp-content/themes/
    Disallow: /wp-login.php
    Disallow: /wp-register.php
    Disallow: /wp-json/
    Disallow: /xmlrpc.php
    Disallow: /?s=*
    Disallow: /search/
    Disallow: /page/
    Disallow: /tag/
    Disallow: /category/
    Disallow: /author/
    Disallow: /date/
    Disallow: /feed/
    Disallow: /comments/feed/
    Disallow: /trackback/
    Disallow: /*/feed
    Disallow: /*?*
    Disallow: /*.pdf$
    
    # Разрешаем индексацию только основных страниц с контентом
    Allow: /$
    
    # Карта сайта (ЗАМЕНИТЕ НА СВОЙ ДОМЕН)
    Sitemap: https://ваш-сайт.ru/sitemap.xml

    Что делает этот файл:

    • Закрывает от индексации служебные папки (/wp-admin/, /wp-includes/ и др.).

    • Закрывает архивы (рубрики, метки, авторы, даты), поиск, пагинацию и страницы с параметрами.

    • Указывает поисковикам путь к карте сайта.

    Важно: Замените https://ваш-сайт.ru на адрес вашего сайта.

    Настройка ЧПУ (постоянных ссылок)

    Зайдите в админку WordPress → «Настройки» → «Постоянные ссылки».

    Выберите вариант «Название записи» (Post name).

    Нажмите «Сохранить изменения».

    Почему это важно: ЧПУ вида https://сайт/название-статьи/ лучше для SEO, чем https://сайт/?p=123.

    Заполнение SEO-полей, Отрывка и SEO для изображений

    9.1. SEO-заголовок и SEO-описание

    Для каждой записи (поста) и страницы:

    • Откройте запись в редакторе.

    • Прокрутите вниз до блока «SEO-настройки».

    • Заполните поле «SEO-заголовок (Title)» — рекомендуемая длина до 60 символов.

    • Заполните поле «SEO-описание (Description)» — рекомендуемая длина 150–160 символов.

    Совет: Заголовок должен содержать ключевое слово и быть привлекательным для клика. Описание — кратко и ёмко передавать суть страницы.

    9.2. Отрывок (Excerpt)

    Отрывок — это краткая выжимка из поста, которая отображается на главной странице, в архивах и в результатах внутреннего поиска. Его тоже нужно заполнять.

    Где находится: В редакторе поста, обычно под основным полем ввода текста (вкладка «Отрывок»). Если её нет — включите через «Настройки экрана» в правом верхнем углу.

    Рекомендуемая длина: 25–35 слов (примерно 150–160 символов).

    Зачем заполнять:

    • Улучшает внешний вид анонсов на сайте.

    • Помогает посетителям быстрее понять, о чём статья.

    • Если SEO-описание не заполнено, WordPress может использовать отрывок как мета-описание.

    9.3. SEO для изображений

    Правильное оформление изображений — важная часть SEO. Для каждого изображения в посте:

    • Заполните атрибут alt (альтернативный текст) — он должен описывать содержание изображения и содержать ключевое слово (если уместно).

    • Дайте файлу осмысленное имя перед загрузкой (например, seo-nastrojka-wordpress.jpg, а не IMG_1234.jpg).

    • Используйте миниатюру поста (Featured Image) — она будет использоваться в Open Graph и Schema-разметке.

    Как заполнить alt в WordPress:

    • При вставке изображения в пост заполните поле «Альтернативный текст».

    • Или в медиатеке откройте изображение и заполните поле «Alt-текст».

    Финальная проверка и отправка sitemap

    10.1. Проверьте работу всех мета-тегов

    Откройте любую страницу сайта, нажмите правой кнопкой мыши → «Посмотреть код страницы» и проверьте наличие:

    • <title> — ваш SEO-заголовок.

    • <meta name="description"> — ваше SEO-описание.

    • Open Graph-теги (og:title, og:description, og:image).

    • Twitter Cards.

    • Schema-разметка (application/ld+json).

    • Каноническая ссылка (<link rel="canonical">).

    10.2. Проверьте sitemap.xml

    Откройте в браузере https://ваш-сайт.ru/sitemap.xml — должен открыться XML-файл со списком всех страниц.

    10.3. Проверьте robots.txt

    Откройте https://ваш-сайт.ru/robots.txt — должен открыться текстовый файл с вашими правилами.

    10.4. Отправьте sitemap в поисковые системы

    Яндекс.Вебмастер:

    • Зайдите в панель Яндекс.Вебмастера.

    • Выберите свой сайт → раздел «Индексирование» → «Sitemap-файлы».

    • Добавьте адрес: https://ваш-сайт.ru/sitemap.xml.

    • Нажмите «Добавить».

    Google Search Console:

    • Зайдите в Search Console → выберите сайт.

    • В левом меню «Sitemap» (или «Карты сайта»).

    • Введите sitemap.xml и нажмите «Отправить».

    Полный список файлов и их назначение

    ФайлМестоположениеНазначение
    style.css/wp-content/themes/название-темы-child/Стили дочерней темы, подключение родительских стилей
    functions.php/wp-content/themes/название-темы-child/ГЛАВНЫЙ ФАЙЛ — содержит весь SEO-код (заголовки, описания, OG, Schema, sitemap и др.)
    robots.txtКорень сайта (/public_html/ или /)Управление индексацией для поисковых роботов

    Что делать, если возникли вопросы?

    Если какой-то шаг непонятен или код не работает — спросите у DeepSeek или другого ИИ-помощника. Опишите проблему максимально подробно:

    • Что вы сделали?

    • Что ожидали увидеть?

    • Что увидели вместо этого?

    • Приложите код (если есть) и сообщение об ошибке (если есть).

    ИИ-помощники отлично справляются с отладкой PHP-кода и могут подсказать, где допущена ошибка.

    А также можете написать мне https://vk.ru/milyutink — я обязательно постараюсь помочь!

    Почему я не стал продавать плагины и начал их отдавать бесплатно.

    Читай также: Почему я взял паузу в разработке и начал писать статьи

  • Почему я не стал продавать плагины и начал их отдавать бесплатно

    Почему я не стал продавать плагины и начал их отдавать бесплатно

    Я прошёл долгий путь от новичка в IT до автора плагина, который официально опубликован в репозитории WordPress.org. Это был тернистый путь. Я пробовал PHP, перешёл на Python, переделывал код с нуля несколько раз, проходил четыре раунда ревью в WordPress.org.

    И вот мой плагин «Milyutin Code Article Reposter for VK» доступен для скачивания. Казалось бы — можно вздохнуть с облегчением и начать зарабатывать.

    Но я принял другое решение. Я не буду продавать свои плагины. Совсем.

    Откуда ноги растут

    Создавать для души — это не про деньги, это про свободу
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Когда я только начинал, я думал как многие: «Сделаю крутой плагин, выложу его в репозиторий, а потом сделаю Pro-версию и буду продавать». Звучит логично, правда? Бесплатная версия привлекает пользователей, платная приносит доход. Freemium-модель работает у тысяч разработчиков.

    Но чем дальше я погружался в разработку, тем больше меня мучил один вопрос: «А хочу ли я этим заниматься?»

    У меня за плечами годы работы в продажах. Я знаю, как это работает изнутри. Ты продаёшь продукт, людям нравится — они молчат. Как только появляется ошибка, баг или что-то идёт не по их плану — на тебя выливают всё, что накопилось. И неважно, что ты делал это бесплатно или за копейки.

    «Когда хорошо — люди молчат, а как только ошибка — всё гавно выливают на тебя». Это не про клиентов. Это про реальность продаж, которую я знаю не понаслышке.

    Я представил, как буду тратить вечера на поддержку платной версии, отвечать на претензии, доказывать, что я не лох, а просто человек, который тоже может ошибаться. И понял: это не моё.

    Момент истины

    Момент истины
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Помню, когда я проходил ревью в WordPress.org, я исправлял одну ошибку за другой. Плагин переделывался с нуля несколько раз. Были моменты, когда я хотел всё бросить. Но я продолжал.

    И в какой-то момент я осознал: я делаю это не ради денег. Я делаю это потому, что мне нравится процесс. Мне нравится решать задачи, создавать что-то полезное, видеть, как мои инструменты помогают другим людям.

    Я вспомнил, зачем вообще начал этот блог. Я хотел делиться опытом, показывать свой код, учиться на ошибках и помогать другим не наступать на те же грабли. А не продавать плагины и беспокоиться о доходах.

    И тогда я принял решение: никаких платных версий. Никаких Pro. Только бесплатные плагины и открытый код.

    Почему бесплатные плагины — это круто

    Почему я не стал продавать плагины

    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я знаю, что многие разработчики скажут: «Но это же нереально. Ты потратил кучу времени, а ничего не заработаешь». Я понимаю этот аргумент. Но у меня другая логика.

    Бесплатные плагины — это моё портфолио.

    Каждый скачанный плагин, каждый отзыв, каждая звезда на WordPress.org — это доказательство того, что я могу делать качественные продукты. Это работает лучше любого резюме.

    Бесплатные плагины — это доверие.

    Когда ты даёшь людям что-то бесплатно и это работает, они начинают тебе доверять. Они подписываются на блог, заходят в группу ВК, следят за новыми проектами. А доверие — это самая ценная валюта в интернете.

    Бесплатные плагины — это обратная связь.

    Я получаю реальные отзывы от реальных пользователей. Они пишут о багах, предлагают улучшения, делятся идеями. Это делает мои плагины лучше. Если бы я продавал их, я бы получал в основном жалобы, а не конструктивную критику.

    Бесплатные плагины — это свобода.

    Я не привязан к доходам. Я могу экспериментировать, пробовать новые подходы, не боясь, что провал ударит по кошельку. Я могу отдать код в открытый доступ, зная, что кто-то может его улучшить.

    Что дальше?

    Почему я не стал продавать плагины
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Мой первый плагин уже доступен всем желающим. Сейчас я работаю над следующими инструментами. И все они тоже будут бесплатными.

    В планах:

    • Плагин для SEO-оптимизации WordPress без лишних надстроек.

    • Python-скрипты для автоматизации рутины.

    • Гайды по установке, настройке и использованию этих инструментов.

    Я продолжу писать в блог, делиться кодом и рассказывать о своих ошибках. Потому что это — моя настоящая ценность. Не плагины, а опыт, который я могу передать другим.

    Призыв к действию

    плагин
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Если ты тоже разработчик-самоучка и стоишь перед выбором: продавать или отдавать бесплатно — послушай себя. Что тебе действительно нравится? Создавать или продавать? Поддерживать пользователей или получать деньги?

    Я выбрал первое. И ни разу не пожалел.

    🔗 Скачай мой плагин бесплатно: wordpress.org/plugins/milyutin-code-article-reposter-for-vk/

    Подписывайся на блог и группу ВК, чтобы не пропустить новые инструменты.

    Контакты

    📧 Email: milyutinkv@gmail.com
    🌐 Сайт: milyutin-codes.ru
    💬 Группа ВК: vk.com/milyutin_codes

    Задавай вопросы, делись идеями, тестируй плагины. Вместе мы строим полезные инструменты!

    Почему я не стал продавать плагины
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Продолжение следует. Новые плагины — уже в разработке. И все бесплатные. Вот первый мой бесплатный плагин.

    Читай также: Почему я взял паузу в разработке и начал писать статьи

    Константин Милютин
    Автор блога «Милютин Код»

  • От идеи до попадания в самое большое хранилище плагинов! Сквозь боль и страдания

    От идеи до попадания в самое большое хранилище плагинов! Сквозь боль и страдания

    Если ты читал мои предыдущие статьи, то знаешь: я прошёл долгий путь от PHP-плагина к Python-скрипту, от бесконечных ошибок к работающей системе автопостинга новостей. Я переосмыслил стратегию блога, отказался от массовой генерации контента и решил создавать полезные инструменты.

    И вот — свершилось!

    Мой плагин «Milyutin Code Article Reposter for VK» официально опубликован в репозитории WordPress.org и доступен для скачивания:

    🔗 wordpress.org/plugins/milyutin-code-article-reposter-for-vk

    Это был долгий и сложный путь. Плагин переделывался с нуля несколько раз. Были моменты, когда я хотел всё бросить и думал, что я себя переоценил в умении общения с ИИ. Но сегодня я хочу рассказать эту историю — от идеи до попадания в самое большое хранилище плагинов в мире. Сквозь боль, страдания и бесконечные правки.

    Часть 1. Как начинались боль и страдания

    Когда я только задумал этот плагин, идея была простая: автоматически публиковать новые статьи из WordPress-блога в группу ВКонтакте. Чтобы не копировать текст вручную каждый раз. Чтобы подписчики видели анонс с картинкой и ссылкой.

    Я написал первую версию на PHP за пару вечеров. Она работала. Плагин брал статью, отправлял в YandexGPT для генерации краткого обзора, получал ответ и публиковал в ВК. Выглядит вроде всё просто.

    Но я решил пойти дальше. Я захотел выложить плагин в официальный репозиторий WordPress.org, чтобы любой владелец сайта мог установить его в один клик.

    И тут начались страдания и боль…

    Часть 2. Первая попытка: отказ и переименование

    Milyutin Code Article Reposter for VK
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я загрузил плагин на review. Через несколько дней пришло письмо от команды WordPress.org.

    Плагин назывался «VK AI Reposter». И это стало первой проблемой.

    «VK» — это зарегистрированный товарный знак третьей стороны, и его использование в начале названия может подразумевать официальную принадлежность к VK.

    Мне предложили переименовать плагин в «Milyutin Code Article Reposter for VK» — с моим именем в начале, чтобы чётко обозначить, что это неофициальный инструмент.

    Я согласился. Изменил название плагина на milyutin-code-article-reposter-for-vk.

    Но это было только начало.

    Часть 3. Технические требования: что пришлось переделывать

    боль и страдания
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Репозиторий WordPress.org — это не просто «залей и готово». Там строгие правила. И мой плагин их нарушал.

    Вот список того, что пришлось исправить:

    Подключение скриптов и стилей

    Вместо прямого вывода <script> и <style> в коде, нужно использовать wp_enqueue_script() и wp_enqueue_style(). Это стандарт WordPress для производительности и совместимости.

    Санитизация и экранирование

    Все данные, приходящие из $_GET, $_POST, $_REQUEST, нужно санитизировать. А все выходные данные — экранировать.

    Например, вместо _e('текст', 'domain') нужно использовать esc_html_e('текст', 'domain').

    Префиксы для всего

    Функции, классы, глобальные переменные, опции — всё должно иметь уникальный префикс, чтобы не конфликтовать с другими плагинами.

    Документирование внешних сервисов

    Плагин использует API ВКонтакте и YandexGPT. Это нужно чётко описать в readme.txt: какие данные отправляются, куда, зачем, и ссылки на политику конфиденциальности.

    Логирование в правильное место

    Я писал логи в папку плагина. Это запрещено. Логи нужно хранить в базе данных или в папке wp-content/uploads с защитой от прямого доступа.

    Не менять глобальные настройки PHP

    set_time_limit(120) на каждом запросе — плохая практика. Нужно ограничивать только те функции, где это действительно необходимо.

    Не использовать cURL напрямую

    Вместо curl_exec() нужно использовать WordPress HTTP API: wp_remote_get(), wp_remote_post().

    Интернационализация

    Все строки должны быть обёрнуты в функции перевода, но без переменных в качестве текста или домена.

    Часть 4. Четыре раунда ревью

    боль и страдания
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Плагин проходил проверку четыре раза. Каждый раз находились новые ошибки. И с каждым разом надежда на то, что мой плагин опубликуют, угасала.

    • Раунд 1: проблемы с названием, документацией, скриптами, экранированием.

    • Раунд 2: битые ссылки на политику конфиденциальности Yandex.

    • Раунд 3: использование cURL вместо HTTP API и проблемы с экранированием nonce.

    • Раунд 4: финальные правки.

    И только после четвёртого раунда пришло письмо:

    Congratulations! The plugin was approved.

    Часть 5. Загрузка в репозиторий через SVN

    Milyutin Code Article Reposter for VK
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    После одобрения нужно было загрузить код через SVN.

    Я очистил локальную папку, сделал svn checkout, скопировал файлы в trunk, создал тег tags/1.0.0 и выполнил svn commit.

    Через несколько минут плагин появился в репозитории.

    Но это получилось со второго раза)

    Часть 6. Что умеет плагин сейчас

    Плагин «Milyutin Code Article Reposter for VK» автоматически публикует новые статьи из вашего блога в группу ВКонтакте.

    Возможности:

    • Автоматическая публикация — срабатывает при публикации поста.

    • Два источника для краткого анонса:

      • YandexGPT — генерирует краткий обзор с помощью нейросети (требуется API-ключ и это платно).

      • Первый абзац — берёт первый абзац статьи. Бесплатно и просто.

    • Загрузка изображений — автоматически находит и загружает обложку, изображение из Gutenberg-блока или первую картинку из контента.

    • Ручная публикация — в редакторе каждого поста есть кнопка «Опубликовать сейчас».

    • Логирование — все действия записываются в отдельный лог-файл, доступный в админке.

    Внешние сервисы:

    • VKontakte API — для публикации постов, загрузки фото и получения информации о группе.

    • Yandex GPT API — для генерации анонсов (опционально и платно).

    Плагин переведён на Английский и Русский языки.

    Часть 7. Что я понял за это время

    1. WordPress.org — это серьёзно.

    Там строгие правила. Но они существуют не для того, чтобы усложнить жизнь, а чтобы обеспечить безопасность и совместимость для миллионов пользователей.

    2. Каждая ошибка — это урок.

    Я никогда не думал о санитизации, экранировании и префиксах так глубоко, как за эти недели. Теперь я понимаю, почему это важно. И главное, теперь я научился писать промпты для ИИ с чётким техническим заданием, а не как писал, когда только начал создавать плагин.

    3. Не сдаваться.

    Были моменты, когда я хотел всё бросить. Но я продолжал. И это окупилось.

    4. Сообщество WordPress — это круто.

    Команда ревьюеров помогла мне сделать плагин лучше. Да, процесс был долгим и мучительным, но результат того стоил.

    Часть 8. Что дальше?

    Плагин уже доступен для скачивания. В планах:

    • Поддержка других социальных сетей (Telegram, ОК, Дзен).

    • Улучшение генерации анонсов.

    • Добавление пагинации и RSS-ленты для новостей.

    • Продолжение изучения SEO без плагинов (в ближайшее время проверю код на тестовом сайте и сразу же перенесу его на этот сайт).

    Призыв к действию

    Если ты тоже разрабатываешь плагин для WordPress — не бойся трудностей. Да, процесс публикации в официальный репозиторий может быть долгим и болезненным. Но это стоит того.

    🔗 Скачай плагин: wordpress.org/plugins/milyutin-code-article-reposter-for-vk

    Установи, настрой за 5 минут и забудь о ручном копировании постов в ВК.

    Боль и страдания Milyutin Code Article Reposter for VK
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Задавай вопросы, делись идеями, тестируй плагин. Вместе мы строим полезные инструменты!

    Продолжение следует. Идеи для новых плагинов — уже в разработке. И я рассматриваю способы, чтобы взять в помощники ChatGPT-4 для написания PHP кода.

    Читай также: Почему я взял паузу в разработке и начал писать статьи

    Константин Милютин
    Автор блога «Милютин Код»

  • От новостного потока к полезным инструментам: как я переосмыслил стратегию блога и создал первый плагин для WordPress

    От новостного потока к полезным инструментам: как я переосмыслил стратегию блога и создал первый плагин для WordPress

    Если ты читал мои предыдущие посты про автоматизацию и упрощение работы с WordPress, ты знаешь: я прошёл долгий путь от PHP-плагина к Python-скрипту, от бесконечных ошибок к работающей системе автопостинга новостей. Я исправил больше 30 ошибок, научил скрипт работать с YandexGPT, извлекать изображения, заполнять SEO и публиковать новости без дубликатов.

    И знаешь что? Я остановил его.

    Не потому, что он сломался. А потому, что я понял: это путь в никуда.

    Сегодня я хочу рассказать, как я переосмыслил стратегию блога, почему отказался от массовой генерации новостей и чем теперь занимаюсь. А главное — поделиться своим первым плагином, который проходит проверку и скоро появится в официальном каталоге WordPress.

    Часть 1. Как я чуть не попал в ловушку

    Python
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Когда я запускал автопостинг новостей через Python-скрипт, я думал: «Чем больше контента — тем лучше. 30 постов в день, и трафик попрёт». Я видел, как плагины вроде BrainyPress, Auto Robot, Texta.ai и ContentPulse обещают «пассивный доход» и «автоматический трафик». И я почти поверил в эту иллюзию.

    Но реальность оказалась куда жёстче.

    В 2026 году Google внедрил систему S-CTS (Scalable Cluster Termination System), которая анализирует не отдельные страницы, а целые сети сайтов. Если ваш сайт публикует сотни однотипных ИИ-статей, вы попадаете в «кластер генерации» — и поисковик просто фильтрует весь сайт целиком. Не отдельные страницы, а именно весь домен.

    Яндекс мыслит схоже. Поисковым системам не важно, кто писал текст — человек или ИИ. Они требуют экспертность, факты, уникальный опыт. Массовая генерация контента работает всё хуже.

    Исследования Ahrefs (июль 2026) показали: 5,3% страниц в топ-3 поиска полностью сгенерированы ИИ. Google не наказывает за сам факт использования ИИ. Но такие страницы получают меньше показов и реже индексируются — не из-за штрафа, а потому что ИИ-контент чаще оказывается поверхностным и не добавляет ценности.

    Ключевой вывод: выигрывает не тот, кто публикует больше, а тот, кто создаёт реальную пользу. В эпоху AI-поиска (ChatGPT, Perplexity, AI Overviews) цитируются сайты с уникальной статистикой, экспертными комментариями и чёткими ответами на вопросы пользователей.

    Часть 2. Как отличить честный инструмент от ловушки?

     WordPress
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Проанализировав рынок плагинов для автопостинга, я увидел пугающую картину:

    • BrainyPress — позиционируется как «полностью автоматизированная контент-машина».

    • Auto Robot — пользователи пишут: «Не покупайте это, оно НЕ работает, автор не отвечает».

    • Texta.ai — рейтинг 3.9 из 405 отзывов, и один из них гласит: «Очередной мошенник забрал деньги и сбежал».

    • UltimateAI — пользователи жалуются: «Парень игнорирует меня, активация не работает».

    • WordPress Automatic Plugin — после обновления генерация контента OpenAI перестала работать.

    Эти плагины продают иллюзию пассивного дохода. «Вставьте ключи API, и сайт наполнится сам». Но в 2026 году эта схема больше не работает.

    Как отличить честный инструмент от ловушки?

    • Честный подход: «ИИ помогает вам писать быстрее, но финальный контент — ваш, с вашей экспертизой». Это инструмент для черновиков и идей.

    • Мошеннический подход: «Вставьте ключи API, и сайт наполнится сам. Вам ничего не нужно делать, только собирать деньги». Это продажа иллюзий.

    Часть 3. Новый путь: от новостей к инструментам

    Милютин Код
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я полностью пересмотрел контент-стратегию для блога «Милютин Код».

    Что уходит в прошлое:

    • Автоматический рерайт новостей через YandexGPT

    • 30+ публикаций в день

    • Поверхностные пересказы чужих статей без моего анализа

    • Новостная страница как отдельный раздел

    Что приходит на смену:

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

    Я буду создавать и публиковать:

    • Готовые PHP-плагины для автопостинга, SEO-оптимизации, работы с API нейросетей

    • Python-скрипты для автоматизации рутинных задач

    • Подробные гайды по установке, настройке и использованию этих инструментов

    • Разборы кода с комментариями, как я их создавал с помощью ИИ

    • Честные обзоры: что работает, а что нет, какие ошибки возникали и как я их чинил

    Вместо того чтобы генерировать новости, я создаю решения, которые помогают другим владельцам сайтов автоматизировать свою работу легально, без риска попасть под фильтры. Это и есть моя экспертиза — я не просто пересказываю чужие новости, я делаю рабочие продукты и делюсь ими.

    Часть 4. Мой первый плагин — в официальном каталоге WordPress!

    milyutin-code-article-reposter-for-vk
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Пока я переосмысливал стратегию, я параллельно работал над инструментом, который действительно приносит пользу. И вот результат — мой плагин milyutin-code-article-reposter-for-vk загружен в репозиторий WordPress.org и проходит финальную проверку модераторами.

    Что умеет плагин?

    Он автоматически публикует новые статьи из вашего блога в группу ВКонтакте — с заголовком, картинкой и кратким анонсом. Анонс можно генерировать через YandexGPT (качественно, но платно) или просто брать первый абзац статьи (бесплатно). Больше не нужно копировать текст вручную — настроил один раз, и всё работает само.

    Почему это работает, а не ломается?

    В отличие от Python-скриптов, которые требуют дополнительно виртуальный сервер для работы, этот плагин написан на PHP и встраивается прямо в WordPress. Он не зависит от внешних серверов, не требует постоянного мониторинга и не конфликтует с другими плагинами. Просто берёт статью, отдаёт нейросети, получает обзор и постит в ВК.

    Что дальше?

    Сейчас плагин проходит проверку, но уже доступен для тестирования в моей группе в ВК. В планах — поддержка других социальных сетей. Это только начало.

    Часть 5. Новый вызов: SEO без плагинов

    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Параллельно с разработкой плагина для ВК я начал изучать, как работает SEO в WordPress без использования плагинов. Почему?

    Потому что популярные SEO-плагины (Yoast, Rank Math, All in One SEO) дают удобный интерфейс, но ограничивают возможности в бесплатных версиях. Чтобы получить полный контроль над мета-тегами, схемами и структурой данных, нужно либо покупать PRO-версии, либо устанавливать ломанные версии, что не есть хорошо.

    Я выбрал второй путь.

    Что я уже изучаю:

    • Как добавлять мета-теги в header.php без плагинов

    • Как формировать правильные Open Graph-теги для соцсетей

    • Как работать с Schema.org разметкой через PHP-фильтры

    • Как оптимизировать заголовки H1-H6 без визуальных редакторов

    Почему это важно?

    SEO без плагинов даёт полный контроль. Вы не зависите от обновлений сторонних разработчиков, не платите за подписки и можете реализовать любую логику, которая нужна именно вашему сайту. Это сложнее, но даёт реальную экспертизу.

    В ближайшее время я планирую:

    • Написать подробный гайд по SEO-оптимизации WordPress без плагинов (для тех, кто любит сложности)

    • Создать свой PHP-плагин-помощник для заполнения SEO-полей (легковесный, без лишнего кода)

    • Сравнить подходы: плагины vs ручная настройка

    Часть 6. Что дальше?

    Новости на сайте остановлены. Плагин автопостинга на основном сайте выключен. Все эксперименты с генерацией контента теперь проходят на тестовом домене.

    Фокус — на полезные инструменты. Плагин для ВК — только первый. В планах:

    • Плагин для автопостинга в Telegram

    • Плагин для внутренней перелинковки

    • Набор PHP-функций для SEO-оптимизации без плагинов

    • Python-скрипты для анализа контента и подсказок по улучшению

    Контента станет меньше, но он станет гораздо полезнее. Вместо 30 новостей в день — один качественный пост с готовым инструментом, который можно скачать, установить и использовать.

    Часть 7. Мои главные выводы

    1. ИИ-контент — это инструмент, а не стратегия.

    Он помогает писать быстрее, но не заменяет экспертизу. Массовая генерация — это путь в никуда.

    2. Полезные инструменты ценнее новостей.

    Люди приходят на сайт не за пересказом чужих статей, а за решениями своих проблем. Плагины, скрипты, гайды — вот что действительно помогает.

    3. SEO без плагинов — это свобода.

    Вы не зависите от сторонних разработчиков и можете реализовать любую логику. Да, это сложнее, но даёт реальное понимание того, как работают поисковые системы.

    4. DeepSeek — идеальный напарник.

    Он помог мне не только с кодом, но и с переосмыслением стратегии. Иногда лучший совет — это не «как сделать», а «стоит ли это делать вообще».

    Призыв к действию

    Если ты тоже думал о покупке плагина для автопостинга ИИ-контента — остановись. Проанализируй, что ты получаешь на самом деле. Возможно, лучше потерять деньги сейчас, чем потратить месяцы на проект, который всё равно приведёт в никуда.

    Подписывайся на группу ВКонтакте, чтобы не пропустить:

    • Выход плагина в официальный каталог WordPress

    • Новые инструменты для автопостинга и SEO

    • Гайды по настройке WordPress без плагинов

    Контакты

    📧 Email: milyutinkv@gmail.com
    🌐 Сайт: milyutin-codes.ru
    💬 Группа ВК: vk.ru/milyutin_codes

    Задавай вопросы, делись идеями, тестируй плагины. Вместе мы строим полезные инструменты!

    Продолжение следует. Скоро — плагин в официальном каталоге и новые инструменты.

    WordPress
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Константин Милютин
    Автор блога «Милютин Код»

     

  • От идеи до работающего автопостинга: как я перешёл с PHP на Python и что из этого вышло

    От идеи до работающего автопостинга: как я перешёл с PHP на Python и что из этого вышло

    Больше месяца я пытался довести до ума PHP-плагин для автопостинга новостей. Исправил 20+ ошибок, научил его работать с YandexGPT, генерировать картинки и заполнять SEO. Но плагин всё равно был капризным — то настройки слетали, то API возвращал 404, то хостинг блокировал соединения.

    Я устал. Не физически, а морально. Каждый день я думал: «Ну сколько можно?» И в какой-то момент я понял, что не обязан биться головой об одну и ту же стену. Можно попробовать другой путь.

    И я попробовал. Я перешёл на Python.

    Сегодня я хочу подвести итог моей работы с DeepSeek за последние недели. Расскажу, что я сделал, с чем столкнулся, какие ошибки уже исправил и какие ещё остались. А главное — поделюсь мыслями о том, что этот проект дал мне как разработчику.

    Часть 1. Почему я вообще начал это делать

    Изначально я хотел создать систему, которая будет:

    • Парсить RSS-ленты ведущих мировых AI-ресурсов.

    • Переводить новости на русский.

    • Делать рерайт, чтобы они были уникальными.

    • Публиковать на моём сайте milyutin-codes.ru.

    • Всё это без моего участия — просто работает и приносит свежий контент.

    Казалось бы, логично — я использую WordPress, значит, и плагин должен быть на PHP. Я написал его, настроил, запустил. И… понеслось.

    С чем я столкнулся:

    • Настройки слетали после каждого обновления.

    • YandexGPT возвращал ошибки 404 из-за устаревшего формата запросов.

    • Хостинг блокировал частые запросы к API.

    • Плагин работал внутри WordPress и конфликтовал с другими плагинами.

    Я потратил неделю, исправил более 20 ошибок, но плагин всё равно оставался нестабильным. И тогда я понял главное: я не хочу быть «администратором» своего плагина. Я хочу, чтобы он просто работал.

    Часть 2. Переход на Python — точка бифуркации

    Когда я задал DeepSeek вопрос: «Может, реализовать автопостинг на Python, если это проще?» — он ответил: «Да, на Python будет проще». И оказался прав.

    Python — это язык для автоматизации. Он не привязан к WordPress, не зависит от версий PHP и не конфликтует с плагинами. Он просто делает свою работу и завершается.

    Что изменилось после перехода:

    • Скрипт работает независимо от сайта.

    • Ошибки не валят WordPress.

    • Я могу запускать его по расписанию через cron.

    • Код стал проще и понятнее.

    Вывод: иногда правильное решение — не «починить» текущую систему, а «пересесть» на другую.

    Часть 3. Эволюция плагина: хронология ключевых изменений

    PHP
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    За время работы я внёс множество доработок. Вот основные этапы:

    4 августа 2026 — Публикация дубликатов из-за неверной проверки

    Проблема: Скрипт проверял дубликаты по переведённому заголовку, который при каждом новом запуске отличался из-за вариативности перевода. Это приводило к многократной публикации одной и той же новости.

    DeepSeek
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Решение: Переработана логика проверки дубликатов. Теперь скрипт использует оригинальный заголовок из RSS и сохраняет RSS GUID в мета-поля поста. При повторной проверке сначала идёт поиск по GUID, затем по нормализованному заголовку (очищенному от кавычек и знаков препинания).

    5 августа 2026 — Ошибка 401 при создании тегов и публикации

    Проблема: WordPress REST API не принимал обычный пароль пользователя, возвращая 401 – rest_cannot_create.

    Решение: В инструкцию добавлено требование использовать пароль приложения (Application Password), создаваемый в профиле пользователя. В коде исправлена авторизация через базовую аутентификацию.

    6 августа 2026 — Парсинг дат работал нестабильно

    Проблема: Скрипт не мог корректно распарсить даты в формате RFC 2822, из-за чего подставлял текущее время, и старые статьи публиковались повторно.

    Решение: Внедрена функция normalize_date(), использующая встроенный парсер feedparser и email.utils. Добавлено извлечение даты из HTML-мета-тегов (article:published_time).

    7 августа 2026 — Логика очереди публикаций

    Проблема: При ручном запуске или по расписанию публиковалась только самая свежая новость, а все остальные терялись.

    Решение: Внедрена система очереди. Новые записи добавляются в список pending_entries в config.json, а затем публикуются по одной при каждом запуске.

    8 августа 2026 — Дублирование при первом запуске

    Проблема: При первом запуске скрипт добавлял в очередь все записи из RSS, включая старые, и начинал их публиковать.

    Решение: Добавлена логика «первого запуска»: если last_published_date отсутствует, публикуется только самая свежая запись, а остальные игнорируются.

    10 августа 2026 — Ошибка 403 от Wordfence при обновлении Rank Math

    Проблема: Плагин безопасности Wordfence блокировал запросы к эндпоинту /rankmath/v1/updateMeta, возвращая 403 Forbidden.

    Решение: Обновление SEO-мета-полей перенесено на стандартный REST API WordPress (/wp/v2/posts/{id}) с передачей данных в поле meta. Добавлен корректный User-Agent.

    11 августа 2026 — Иерархические категории

    YandexGPT
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Проблема: Все новости публиковались в одну категорию, без структурирования по темам.

    Решение: Реализована иерархическая система категорий:

    • Родительская категория: «Новости ИИ» (slug: novosti-ii).

    • Дочерние подрубрики: 9 штук + «Разное» для нераспознанных новостей.

    • Автоматическое создание недостающих категорий при первом запуске.

    12 августа 2026 — Определение компании и перевод длинных статей

    YandexGPT
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Проблема:

    • Названия компаний переводились на русский, терялась идентичность.

    • Статьи длиннее 2500 символов обрезались или переводились с ошибками.

    Решение:

    • Добавлена функция extract_company_name(), которая отдельным запросом к YandexGPT определяет главную компанию (на английском) и использует её в SEO-полях и alt-текстах.

    • Реализована разбивка длинных текстов на части (split_text_into_chunks()), каждая часть переводится отдельно, затем результаты склеиваются.

    17 августа 2026 — Очистка ответов YandexGPT

    Проблема: В названиях компаний появлялись лишние слова («Amazon Вопрос», «Meta Вопрос»), а иногда скрипт не мог распарсить ответ.

    Решение: Ужесточены промпты для YandexGPT, добавлена очистка ответов от стоп-слов и переносов строк. Введена повторная попытка генерации заголовка и тегов с альтернативным форматом.

    Часть 4. Что я получил в итоге

    Python
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    После всех доработок плагин:

    • Публикует новости строго по очереди, без дубликатов.

    • Корректно определяет компании и использует их в SEO.

    • Автоматически создаёт иерархию категорий.

    • Переводит статьи любого объёма (разбивка на части).

    • Обновляет SEO-поля Rank Math через стандартный REST API.

    • Работает 24/7 на сервере как systemd-служба.

    • Извлекает изображения из оригинальных статей и вставляет их в пост.

    • Очищает текст от рекламы и мусора.

    • Добавляет ссылку на источник в виде аккуратного домена.

    Часть 5. Что ещё осталось исправить

    RSS
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Плагин работает, но всё ещё есть мелкие ошибки, которые я исправляю в данный момент:

    • Иногда YandexGPT возвращает 400 — если промпт слишком длинный или формат нарушен. Добавил обрезку текста до 3000 символов и логирование ответа, но иногда ошибка всё равно возникает.

    • Изображения не всегда загружаются — если URL картинки битый или сайт блокирует запросы. Пока просто пропускаю, но планирую добавить повторные попытки.

    • SEO-поля Rank Math обновляются не всегда — иногда API возвращает 404, если пост только что создан. Добавил задержку перед обновлением мета-полей.

    • На тестовом домене иногда слетают настройки — потому что я часто перезапускаю скрипт и меняю конфиг. Это не критично, но нужно будет исправить.

    • Некоторые RSS-ленты не парсятся — если сайт использует нестандартный формат или требует авторизации.

    Но я не отчаиваюсь. Каждая ошибка — это урок. И я исправляю их одну за другой.

    Часть 6. Мои главные выводы

    1. Не бойтесь менять инструменты.

    Если PHP-плагин не работает — напишите на Python. Это быстрее, чем пытаться «починить» то, что сломано по своей сути.

    2. Качество контента — это не только текст.

    Картинки, структура, категории — всё это влияет на восприятие. ИИ может помочь с текстом, но структуру и логику контента должен продумывать человек.

    3. Автоматизация не заменяет человека.

    Я автоматизировал сбор, перевод и публикацию новостей. Но я всё равно проверяю их, редактирую, если нужно, и думаю о том, как улучшить систему.

    4. ИИ — это инструмент, а не волшебная таблетка.

    YandexGPT помогает мне писать тексты, но я отвечаю за то, как они звучат. Python помогает мне автоматизировать рутину, но я отвечаю за то, как система работает.

    5. DeepSeek — идеальный напарник.

    Он объясняет, подсказывает, исправляет ошибки и не даёт опустить руки. Без него я бы не справился.

    Часть 7. Что дальше?

    Как только я исправлю все оставшиеся мелкие ошибки, я выложу код плагина в свободный доступ на своём сайте. Чтобы любой желающий мог скачать его, настроить под себя и использовать для своего WordPress-сайта.

    В ближайших планах:

    • Добавить поддержку нескольких RSS-источников одновременно.

    • Реализовать более умное распознавание ключевых сущностей.

    • Внедрить логирование в базу данных для статистики.

    • Добавить пагинацию на страницах «Блог» и «Новости ИИ».

    • Настроить RSS-ленту для новостей.

    Призыв к действию

    Если ты тоже разработчик-самоучка и иногда чувствуешь, что застрял — вспомни мою историю. Иногда правильнее не биться головой о стену, а найти обходной путь. Взять паузу. Сделать шаг назад, чтобы потом прыгнуть дальше.

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

    Python-скрипт
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Контакты

    📧 Email: milyutinkv@gmail.com
    🌐 Сайт: milyutin-codes.ru
    💬 Группа ВК: vk.ru/milyutin_codes

    Задавай вопросы, делись идеями, пиши свои истории. Мы вместе.

    Продолжение следует. Скоро — открытый код.

    Константин Милютин
    Автор блога «Милютин Код»

  • Как я перешёл с PHP на Python для автопостинга: первые шаги и текущие ошибки

    Как я перешёл с PHP на Python для автопостинга: первые шаги и текущие ошибки

    Больше недели я пытался довести до ума PHP-плагин для автопостинга новостей. Исправил 20+ ошибок, научил его работать с YandexGPT, генерировать картинки и заполнять SEO. Но плагин всё равно был капризным — то настройки слетали, то API возвращал 404, то хостинг блокировал соединения.

    Я устал. Не физически, а морально. Каждый день я думал: «Ну сколько можно?» И в какой-то момент я понял, что не обязан биться головой об одну и ту же стену. Можно попробовать другой путь.

    И я попробовал. Я перешёл на Python.

    Python
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Сегодня я расскажу, как я с DeepSeek за несколько дней создал полноценный Python-скрипт с графическим интерфейсом, который автоматически парсит RSS, переводит новости, публикует их в WordPress и заполняет SEO. Пока он работает на тестовом домене и не идеален — но прогресс есть, и я хочу поделиться этим опытом.

    Если ты пропустил предыдущую часть, вот ссылка: Шестой день с DeepSeek: не забрасываю плагин — просто беру паузу, чтобы ускорить наполнение сайта. А сейчас — свежий отчёт о том, что я сделал, с чем столкнулся и куда двигаюсь дальше.

    Почему Python, а не PHP?

    Я не профессиональный PHP-разработчик. Я — самоучка, который учится на ходу. PHP-плагин требовал глубокого погружения в экосистему WordPress: хуки, фильтры, WP-Cron, правила безопасности. Каждая правка отнимала часы. А Python — это независимая программа. Она просто общается с WordPress через REST API и делает только то, что я ей скажу. Никаких ограничений ядра, никаких неожиданных сбоев из-за плагинов.

    DeepSeek сразу сказал: «Да, на Python будет проще». И оказался прав.

    Что я сделал за это время

    1. Графический интерфейс — для тех, кто не любит консоль

    Я хотел, чтобы скриптом мог пользоваться даже человек, который никогда не видел командной строки. Поэтому я создал GUI на tkinter. Три вкладки:

    • Настройки — поля для API-ключа Yandex, Folder ID, URL сайта, логина, пароля приложения, RSS-лент, SMTP и словаря категорий. Всё сохраняется в config.json.

    • Управление — кнопки «Запустить сейчас» (обрабатывает только одну новость), «Запустить по расписанию» (каждый час) и «Остановить». Там же — окно с логами в реальном времени.

    • Статистика — общее количество опубликованных новостей и последние 5 постов.

    Создать такой интерфейс с DeepSeek было просто: он предложил структуру окон, поля и привязку к сохранению настроек.

    2. Парсинг RSS и статей — без headaches

    Для RSS я использовал feedparser. Он отлично парсит любые ленты — даже те, где кривая структура. А для извлечения полного текста и изображений из оригинальной статьи — newspaper3k. Эта библиотека умеет скачивать страницу, находить основной контент, удалять рекламу и собирать все изображения.

    Правда, пришлось повозиться с зависимостями: на Windows newspaper3k требует lxml_html_clean и ресурсы NLTK (punkt_tab). DeepSeek подсказал, как это установить, и через пару команд всё заработало.

    3. Интеграция с YandexGPT — перевод и рерайт

    YandexGPT
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Самый важный этап — отправка текста в YandexGPT. Я использовал актуальный эндпоинт:

    text
    https://llm.api.cloud.yandex.net/foundationModels/v1/completion

    Формат запроса — messages с ролями system и user. Ключевой момент: в поле messages нужно использовать ключ text, а не content (я долго ловил эту ошибку 400). После исправления всё полетело.

    Промпт для YandexGPT просит перевести текст на русский, сделать его уникальным, предложить новый заголовок и 5 тегов. Ответ парсится по маркерам ЗАГОЛОВОК:, ТЕГИ:, ТЕКСТ:. Всё просто и надёжно.

    4. Сохранение структуры — изображения на своих местах

    Одна из главных проблем была — как вставить изображения в те же позиции, где они были в оригинале. Я решил это так:

    • Извлекаю структурированный контент через article.clean_top_node.

    • Прохожу по нему, собирая последовательность текстовых блоков и изображений.

    • Переведённый текст разбиваю на абзацы пропорционально количеству оригинальных текстовых блоков.

    • Собираю финальный HTML, чередуя абзацы и изображения в нужном порядке.

    Это даёт почти идеальное совпадение с оригиналом. И да, первое изображение становится миниатюрой поста (featured image) с правильным ALT-текстом.

    5. SEO для Rank Math — автоматически

    Rank Math
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Раньше я заполнял SEO вручную. Теперь всё автоматически:

    • Фокусный ключевик выделяется через YandexGPT (или извлекается из заголовка).

    • Мета-описание генерируется отдельным запросом к YandexGPT.

    • Формируется SEO-заголовок вида {focus_keyword} - {post_title}.

    • Дополнительные ключевики (до 4) добавляются через запятую.

    Все эти данные обновляются через REST API Rank Math (/wp-json/rankmath/v1/updateMeta). После публикации поста достаточно одного запроса — и все поля Rank Math заполнены.

    6. Проверка дубликатов — чтобы не было повторов

    Чтобы не публиковать одну и ту же новость дважды, я реализовал умную проверку:

    • Нормализую заголовок (убираю кавычки, лишние пробелы, пунктуацию, привожу к нижнему регистру).

    • Ищу посты с таким же нормализованным заголовком через REST API.

    • Если нахожу — пропускаю публикацию.

    Это работает даже если в RSS заголовок немного отличается от сохранённого в WordPress. Теперь дубликатов нет.

    7. Ссылка на источник — только домен

    Вместо громоздкого URL я показываю только домен (без www.). Это делает ссылку аккуратной и читаемой.

    8. Расписание — каждый час

    Скрипт можно запускать по расписанию через schedule. Каждый час он проверяет RSS-ленту, берёт самую свежую новость и публикует её (если она ещё не опубликована). Если новостей нет — просто ждёт следующего часа.

    Что я получил на данный момент

    На тестовом домене скрипт уже работает. Он:

    • парсит RSS,

    • извлекает полный текст и изображения,

    • переводит и рерайтит через YandexGPT,

    • сохраняет структуру абзацев и позиции изображений,

    • публикует посты в WordPress,

    • заполняет SEO-поля Rank Math,

    • устанавливает миниатюру с ALT-текстом,

    • проверяет дубликаты,

    • отправляет дайджест на email,

    • работает по расписанию.

    Но идеально пока не всё. Есть ошибки, которые я исправляю.

    Какие ошибки я сейчас исправляю

    • Проблемы с NLTK на сервере — пришлось вручную скачивать punkt_tab и указывать путь к данным.

    • Иногда YandexGPT возвращает 400 — если промпт слишком длинный или формат нарушен. Добавил обрезку текста до 3000 символов и логирование ответа.

    • Изображения не всегда загружаются — если URL картинки битый или сайт блокирует запросы. Пока просто пропускаю, но планирую добавить повторные попытки.

    • SEO-поля Rank Math обновляются не всегда — иногда API возвращает 404, если пост только что создан. Добавил задержку перед обновлением мета-полей.

    • На тестовом домене иногда слетают настройки — потому что я часто перезапускаю скрипт и меняю конфиг. Это не критично, но нужно будет исправить.

    Но я не отчаиваюсь. Каждая ошибка — это урок. И я исправляю их одну за другой.

    Что дальше?

    Я продолжу тестировать скрипт на тестовом домене, пока не уберу все ошибки. Планирую:

    • Улучшить обработку изображений (добавить повторные попытки загрузки).

    • Настроить более гибкое расписание (можно будет выбирать интервал).

    • Добавить поддержку нескольких RSS-лент с разными категориями.

    • Оптимизировать запросы к YandexGPT, чтобы экономить токены.

    А когда скрипт будет стабилен — перенесу его на боевой сайт и запущу в полноценную работу.

    Что я понял за эти дни

    • Не бойся пробовать новое. Если что-то не идёт — попробуй другой путь. Это не поражение, это стратегия.

    • Python — это не замена PHP, а дополнение. У каждого инструмента своя ниша. Для внешней автоматизации Python — лучший выбор.

    • DeepSeek — не просто помощник, а наставник. Он объясняет, подсказывает, исправляет ошибки и не даёт опустить руки.

    • Графический интерфейс — это круто. Даже если ты не программист, приложение с GUI делает настройку и запуск интуитивно понятными.

    • Этот путь — долгий. И в нём есть место для обходных путей, экспериментов и пауз. Главное — не останавливаться.

    Призыв к действию

    Если ты тоже разработчик-самоучка и иногда чувствуешь, что застрял — вспомни мою историю. Иногда правильнее не биться головой о стену, а найти обходной путь. Взять паузу. Сделать шаг назад, чтобы потом прыгнуть дальше.

    Подписывайся на мой блог, чтобы не пропустить следующую главу. Я расскажу, как настраивал скрипт на VPS и решал последние проблемы с хостингом.

    Контакты

    📧 Email: milyutinkv@gmail.com
    🌐 Сайт: milyutin-codes.ru
    💬 Группа ВК: vk.ru/milyutin_codes

    Задавай вопросы, делись идеями, пиши свои истории. Мы вместе.

    Продолжение следует. Следите за обновлениями.

    YandexGPT
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Константин Милютин
    Автор блога «Милютин Код»

  • Шестой день с DeepSeek: не забрасываю плагин — просто беру паузу, чтобы ускорить наполнение сайта

    Шестой день с DeepSeek: не забрасываю плагин — просто беру паузу, чтобы ускорить наполнение сайта

    Я работаю с DeepSeek. Если ты читаешь этот пост, значит, ты уже прошёл со мной путь от первой идеи до пятого дня, когда я осознал, что ошибка была не в коде, а в платном источнике новостей.

    Я честно признаюсь: PHP-плагин оказался сложнее, чем я думал. Я уже пять дней борюсь с багами, настройками, ошибками API и ограничениями хостинга. И хотя я исправил больше 20 проблем, плагин всё ещё не работает идеально.

    Но я не сдаюсь. И не забрасываю плагин на PHP.

    Я просто беру паузу, чтобы решить другую задачу: ускорить наполнение своего сайта новостями. А заодно — протестировать альтернативный подход. Потому что иногда правильнее сделать шаг назад, чтобы потом прыгнуть дальше.

    Если ты пропустил предыдущую часть, вот ссылка: Пятый день с DeepSeek: перерыв помог — я нашёл ошибку, и она оказалась совсем не в коде. А сейчас — мой шестой день, день стратегического решения и нового направления.

    Утро шестого дня: вопрос, который перевернул всё

    Я сидел и думал: «Плагин на PHP почти готов, но возни с ним ещё много. Может, есть способ быстрее начать публиковать новости?»

    Я открыл чат с DeepSeek и задал вопрос, который давно вертелся в голове:

    «Плагин на PHP не получается довести до ума, точнее я хочу довести до ума его, но много занимает времени. Может, реализовать автопостинг новостей по принципу как в плагине, но только через Python, если это проще?»

    DeepSeek ответил неожиданно честно: «Да, реализовать автопостинг на Python действительно проще». И объяснил почему.

    Почему Python проще, чем PHP-плагин?

    DeepSeek
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    DeepSeek сравнил две задачи:

     
     
    PHP-плагинPython-скрипт
    Глубокое погружение в экосистему WordPressНезависимая программа
    Требует знания хуков, фильтров, WP-CronПросто общается с WordPress через REST API
    Код работает внутри системы — много ограниченийДелает только то, что я ему скажу
    Сложно отлаживатьЛегко тестировать и изменять по частям

    И это действительно так. Python — идеальный выбор для задач автоматизации. Он позволяет создать гибкий пайплайн, который легко тестировать, модифицировать и запускать по расписанию.

    Что может делать Python-скрипт для автопостинга?

    DeepSeek перечислил ключевые возможности:

    • Парсить RSS и получать новости.

    • Переводить контент с английского на русский (через YandexGPT).

    • Обрабатывать текст (рерайт, генерация заголовка, тегов).

    • Генерировать изображения через YandexART.

    • Публиковать посты через WordPress REST API.

    • Работать по расписанию через cron на сервере.

    И самое главное — всё это можно сделать в виде независимого скрипта, который не зависит от архитектуры WordPress.

    Архитектура Python-решения

    DeepSeek
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    DeepSeek предложил создать не один монолитный скрипт, а несколько независимых компонентов:

    • Скрипт-планировщик — запускается по cron каждый час.

    • Парсер — подключается к RSS-лентам и забирает новости.

    • Генератор — отправляет текст в YandexGPT и получает обработанный контент.

    • Публикатор — через WordPress REST API создаёт посты, назначает рубрики, теги и обложки.

    Такой подход гораздо более модульный. Если что-то сломается (например, изменится API Яндекса), я легко найду и исправлю проблему.

    Что я решил сделать

    PHP
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я не отказываюсь от PHP-плагина. Он останется как долгосрочное решение — полноценный инструмент, который будет жить внутри WordPress.

    Но сейчас, пока я довожу плагин до ума, я хочу быстро начать наполнять сайт новостями. Поэтому я решил:

    1. Создать Python-скрипт для автопостинга.

    2. Настроить его на работу с бесплатными RSS-источниками (Google News, The Verge, VentureBeat).

    3. Запустить его на VPS (выбрал Beget) по расписанию.

    4. Использовать его как временное решение, пока PHP-плагин не будет готов.

    Это даст мне:

    • Свежие новости на сайте каждый день.

    • Возможность тестировать разные форматы контента.

    • Понимание того, как работает автопостинг «снаружи» WordPress.

    • Опыт работы с Python, который пригодится в будущем.

    Какой продукт я купил на Beget

    Python
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Для запуска Python-скрипта мне нужен был не обычный хостинг, а VPS. На обычном хостинге:

    • время выполнения скриптов строго ограничено,

    • фоновые задачи работают нестабильно,

    • нельзя установить нужные версии Python и библиотеки.

    Я выбрал VPS на Beget с такой конфигурацией:

    • ОС: Ubuntu 22.04 LTS

    • Процессор: 2 ядра

    • Оперативная память: 4 ГБ

    • Диск: 40 ГБ NVMe

    Это стоит примерно 390–510 ₽ в месяц (плюс 150 ₽ за IPv4-адрес). Вполне приемлемо для стабильной работы скрипта.

    Что дальше?

    Python
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я уже подготовил подробный промпт для DeepSeek, который поможет мне создать Python-скрипт с графическим интерфейсом. В нём будут:

    • Удобные поля для ввода настроек (API-ключи, RSS-ссылки, email).

    • Кнопки «Запустить сейчас» и «Запустить по расписанию».

    • Поле для вывода логов в реальном времени.

    • Сохранение настроек в файл config.json.

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

    А PHP-плагин я продолжу дорабатывать в фоновом режиме. Он станет моим «взрослым» решением, когда я буду полностью уверен в его стабильности.

    Что я понял за шесть дней

    • Не обязательно выбирать что-то одно. Можно использовать два инструмента параллельно — временный и основной.

    • Python действительно проще для автоматизации. Иногда правильнее выйти за рамки экосистемы и сделать независимый скрипт.

    • VPS — это необходимость. Для фоновых задач и долгих процессов обычный хостинг не подходит.

    • Не нужно гнаться за результатом. Этот путь — долгий, и в нём есть место для обходных путей.

    • DeepSeek — не просто помощник, а стратег. Он помогает не только с кодом, но и с выбором правильного направления.

    Итог: я не забрасываю плагин — я беру паузу

    Плагин на PHP остаётся в разработке. Я вернусь к нему, когда у меня будет больше времени и сил. А пока я запускаю Python-скрипт, который будет автоматически наполнять сайт новостями.

    Это не отказ от мечты. Это стратегический манёвр.

    Если ты тоже разработчик-самоучка и иногда чувствуешь, что застрял — вспомни мою историю. Иногда правильнее не биться головой о стену, а найти обходной путь. Взять паузу. Сделать шаг назад, чтобы потом прыгнуть дальше.

    Подписывайся на мой блог, чтобы не пропустить следующую главу. Я расскажу, как создавал Python-скрипт с графическим интерфейсом и настраивал его на VPS.

    Контакты

    📧 Email: milyutinkv@gmail.com
    🌐 Сайт: milyutin-codes.ru
    💬 Группа ВК: vk.ru/milyutin_codes

    Задавай вопросы, делись идеями, пиши свои истории. Мы вместе.

    Продолжение следует. Теперь — с Python.

    Python
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Константин Милютин
    Автор блога «Милютин Код»

     

  • Пятый день с DeepSeek: перерыв помог — я нашёл ошибку, и она оказалась совсем не в коде

    Пятый день с DeepSeek: перерыв помог — я нашёл ошибку, и она оказалась совсем не в коде

    Я работаю с DeepSeek. Если ты читаешь этот пост, значит, ты уже прошёл со мной путь от первой идеи до четвёртого дня, когда я взял паузу, чтобы не сойти с ума. Я честно признался, что устал, что упёрся в стену, и мне нужно время, чтобы осмыслить происходящее.

    И знаешь что? Перерыв сработал.

    Я отвлёкся, выдохнул, переключился на другие дела. А когда через пару дней вернулся к коду, меня осенило. Ошибка была не в коде. Она была в том, откуда я беру новости.

    Если ты пропустил предыдущую часть, вот ссылка: Четвёртый день с DeepSeek: почти финиш, но я взял паузу. А сейчас — мой пятый день, день осознания и нового начала.

    Утро пятого дня: отдохнувший мозг видит яснее

    Я открыл чат с DeepSeek после перерыва и сказал: «Я понял. Плагин работает идеально на моём локальном сервере. Но на боевом хостинге он не может скачать RSS-ленту Technology Review. Я увеличивал таймауты, добавлял повторные попытки, кеширование — ничего не помогает».

    DeepSeek спросил: «А что, если проблема не в технической части? Может быть, сайт просто не отдаёт полный контент?»

    И тут меня осенило. Я зашёл на сайт Technology Review в обычном браузере и увидел это: замок. Статья требовала подписки. Полный текст был доступен только платным пользователям. RSS-лента отдавала только анонсы — те самые несколько предложений, которые я видел в постах.

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

    Что я сделал за этот день

    Даже несмотря на осознание, что Technology Review — платный, я продолжил улучшать плагин. Потому что другие источники будут работать. И я хочу, чтобы плагин был готов к любым условиям.

    Окончательно починил сохранение настроек

    Настройки теперь сохраняются идеально. Я переделал class-settings.php так, что все поля в одной форме, вкладки — просто навигация. Галки не слетают. Никогда.

    Очистка контента — теперь идеальная

    Я добавил комплексную очистку: удаляю **, ###, ---, обратные кавычки, множественные пробелы, пробелы перед знаками препинания. Контент стал кристально чистым.

    php
    private function clean_markdown( $text ) {
        $patterns = [
            '/\*\*/', '/__/', '/#{2,}/', '/-{2,}/', '/\*{2,}/', '/_{2,}/', '/\s{2,}/', '/```/'
        ];
        $text = preg_replace( $patterns, ' ', $text );
        return trim( preg_replace( '/\s+/', ' ', $text ) );
    }

    Ключевик — теперь главная сущность

    Я добавил метод, который через GPT выделяет главную сущность: название продукта, имя человека, компанию. Больше никаких предлогов в ключевике.

    Ключевик в первом абзаце — естественно

    Теперь ключевик вставляется как часть предложения, выделяясь жирным, без лишних тире и двоеточий.

    Убрал принудительный H2

    Подзаголовки теперь генерируются GPT органично. Без штампов.

    Объём контента — 600–800 слов

    Увеличил max_tokens до 3000, добавил требование к объёму в промпт. Статьи стали полноценными.

    Ссылка на источник — только домен

    Вместо полного URL показываю technologyreview.com. Кратко и понятно.

    Дубли исключены

    Механизм запоминания ссылок работает надёжно. Каждая новость публикуется только один раз.

    Изображения из RSS — с повторными попытками

    Плагин ищет картинку в media:content, enclosure, или берёт первое img из контента. При ошибке — повторяет попытку.

    Кеширование RSS для устойчивости

    Я добавил кеширование RSS-ответа на 1 час через set_transient(). Если лента недоступна, плагин использует кеш.

    Перевод контента на русский

    Все промпты теперь содержат требование «на РУССКОМ языке». Контент стал полностью русскоязычным.

    Главное открытие: ошибка была в источнике, не в коде

    Когда я понял, что Technology Review — платный, я почувствовал облегчение. Потому что это означало, что мой плагин работает правильно. Он делал всё, что должен. Просто получал то, что ему отдавали.

    DeepSeek сразу предложил альтернативные бесплатные RSS-источники. Вот некоторые из них:

    DeepSeek рекомендовал начать с Google News — это бесплатно, стабильно и без подписки. Я так и сделал.

    Что я понял за пять дней

    • Перерыв — это инструмент. Когда я отвлёкся, мозг продолжал работать в фоновом режиме и нашёл решение.

    • Ошибка может быть не в коде. Иногда проблема в окружении, в источнике данных, в бизнес-логике.

    • Не нужно гнаться за результатом. Этот путь — долгий. И он того стоит.

    • DeepSeek — не просто помощник. Он стал моим напарником, который не даёт опустить руки.

    • Плагин работает. И он будет работать ещё лучше с правильными источниками.

    Плагин не работает идеально, но я на верном пути

    Плагин «Autonews Publisher» сейчас полностью готов к работе. Он:

    • сохраняет настройки,

    • парсит RSS,

    • очищает контент,

    • генерирует статьи через YandexGPT,

    • добавляет SEO,

    • подгружает изображения,

    • исключает дубли.

    Единственное, что осталось — выбрать правильные RSS-источники. И это уже не техническая проблема, а стратегическая.

    Что дальше?

    Я начну тестировать плагин с новыми источниками — Google News, The Verge, VentureBeat. Уверен, что результаты будут отличными.

    А ещё я продолжу писать этот дневник. Потому что даже после финала плагина — это история о том, как человек учится, ошибается, отдыхает и идёт дальше.

    Призыв к действию

    Если ты тоже разрабатываешь что-то сложное — не забывай про отдых. Иногда лучший способ решить проблему — отойти от неё. Дать себе время. Посмотреть на неё свежим взглядом.

    Подписывайся на мой блог, чтобы не пропустить следующую главу. Я почти у цели.

    Контакты

    📧 Email: milyutinkv@gmail.com
    🌐 Сайт: milyutin-codes.ru
    💬 Группа ВК: vk.ru/milyutin_codes

    Задавай вопросы, делись идеями, пиши свои истории. Мы вместе.

    Ключевая фраза

    Ошибка была не в коде — она была в источнике.

    Продолжение следует. Теперь — с новыми источниками.

    Константин Милютин
    Автор блога «Милютин Код»

  • Четвёртый день с DeepSeek: почти финиш, но я взял паузу, чтобы не сойти с ума.

    Четвёртый день с DeepSeek: почти финиш, но я взял паузу, чтобы не сойти с ума.

    Я работаю с DeepSeek. Если ты читаешь этот пост, значит, ты уже прошёл со мной путь от первой идеи до третьего дня отладки. Я создавал плагин «Autonews Publisher», ловил баги, исправлял ошибки, и сегодня — четвёртый день — я почти у цели. Почти.

    Но сегодня я хочу рассказать не только о том, как я решил ещё 11 проблем. Я хочу рассказать о том, почему я решил сделать перерыв. Потому что иногда, чтобы понять, где ошибка, нужно остановиться, выдохнуть и посмотреть на код свежим взглядом. Не гнаться за результатом, а принять, что этот путь — долгий. И это нормально.

    Если ты пропустил предыдущие части, вот ссылка: Третий день с DeepSeek. А сейчас — мой четвёртый день.

    Утро четвёртого дня: план и реалии для плагина

    DeepSeek
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я открыл чат с DeepSeek и сказал: «Давай подведём итог. Что мы сделали, что осталось, и где мы сейчас?» Я уже исправил 13 ошибок в третий день, но оставались ещё нюансы: маркдаун-символы в тексте, слишком длинные URL, ключевики с предлогами, дубли новостей и, самое обидное, таймауты при подключении к RSS-лентам.

    DeepSeek снова взялся за работу. Я систематизировал все задачи и пошёл по списку. Вот что я сделал за этот день.

    Что я исправил в четвёртый день с DeepSeek

    DeepSeek
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    1. Сохранение настроек — окончательно и бесповоротно

    Настройки больше не слетают. Я переделал class-settings.php так, что все поля теперь в одной форме, а вкладки — просто навигация. При сохранении отправляются все данные, галки не сбрасываются. Теперь я могу спокойно переключаться между вкладками и не бояться, что что-то потеряется.

    2. Очистка контента от маркдаун-символов

    В статьях появлялись артефакты: **, ##, ---, лишние пробелы, даже буква «с» в начале. DeepSeek написал метод clean_markdown(), который удаляет всё это безобразие.

    php
    private function clean_markdown( $text ) {
        $patterns = [
            '/\*\*/', '/__/', '/#{2,}/', '/-{2,}/', '/\*{2,}/', '/_{2,}/', '/\s{2,}/'
        ];
        $text = preg_replace( $patterns, ' ', $text );
        return trim( preg_replace( '/\s+/', ' ', $text ) );
    }

    Теперь контент выглядит как полноценная статья, а не черновик из редактора.

    3. Корректное формирование фокусного ключевика

    Раньше ключевик обрезался до предлогов: «Искусственный интеллект в». DeepSeek предложил метод, который отсекает предлоги и союзы, оставляя только значимые слова — существительные и прилагательные. Теперь ключевик звучит осмысленно, например: «Искусственный интеллект разработка лекарств».

    4. Ключевик в первом абзаце — без лишних символов

    Раньше я вставлял ключевик с тире и двоеточием, что выглядело неестественно. Теперь он встраивается как часть предложения, выделяясь жирным шрифтом. Читабельно и без мусора.

    5. Убрал принудительный H2

    Я раньше добавлял искусственный подзаголовок «КЛЮЧЕВИК: ключевые аспекты», и это выглядело странно. Теперь я полагаюсь на GPT: в промпте рерайта я прошу нейросеть добавлять подзаголовки с ключевиком органично. Получается естественно и без штампов.

    6. Увеличил объём контента до 600+ слов

    Статьи были короткими — около 500 слов. Я увеличил max_tokens до 3000 и добавил в промпт требование «не менее 600 слов». Теперь GPT выдаёт статьи на 600–800 слов, что хорошо для SEO.

    7. Сократил постоянную ссылку (slug)

    URL был длиной 96 символов — слишком много. Я обрезаю slug до 60 символов и удаляю лишние окончания. Теперь ссылки аккуратные.

    8. Ссылка на источник — только домен

    Вместо полного URL я показываю только домен: technologyreview.com. Кратко и понятно.

    9. Предотвратил дублирование новостей

    Плагин больше не публикует одну и ту же новость дважды. Я добавил механизм, который запоминает ссылки опубликованных постов в опции autonews_published_links. Перед публикацией проверяю, не было ли уже этой ссылки.

    10. Извлечение изображений из RSS

    Теперь, если генерация картинок отключена, плагин ищет изображение в RSS: в media:content, в enclosure, или берёт первое img из контента. И устанавливает его как обложку с ALT = фокусный ключевик.

    11. Увеличен таймаут для RSS

    Но вот тут я упёрся в стену. Хостинг не даёт подключиться к www.technologyreview.com — таймаут 10 секунд. Я увеличил таймаут до 60 секунд, добавил повторные попытки (до 3-х с паузой 3 секунды), установил User-Agent. Но проблема не в коде. Она в хостинге.

    Не решённая проблема: хостинг блокирует RSS

    deepseek
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Я сделал всё, что мог. Код плагина готов. Он работает локально, на тестовом сервере — идеально. Но на боевом хостинге, где я размещаю свой сайт, исходящие соединения на порт 443 ограничены. Это значит, что плагин не может скачать RSS-ленту.

    DeepSeek предложил обратиться в поддержку хостинга с просьбой:

    • разрешить внешние HTTP-запросы,

    • увеличить max_execution_time до 120 секунд,

    • отключить ограничения allow_url_fopen.

    Но это требует времени. И я принял решение: не гнаться за результатом.

    Почему я решил сделать перерыв

    deepseek
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Когда ты 4 дня подряд сидишь с кодом, общаешься с нейросетью, правишь баги, тестируешь, и на финишной прямой упираешься в стену — легко выгореть. Я понял, что если буду давить дальше, то перестану получать удовольствие от процесса. А ведь именно ради удовольствия я и начал этот проект.

    Я решил взять паузу. На пару дней отвлечься, переключиться, дать мозгу переварить информацию. Потому что иногда, чтобы найти решение, нужно отойти от задачи. Посмотреть на неё свежим взглядом. Осмыслить.

    Это не поражение. Это зрелость.

    Что я понял за четыре дня

    DeepSeek
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru
      • Плагин почти готов. Код работает, SEO-ошибки исправлены, контент очищен, дубли исключены. Осталось только решить вопрос с хостингом.

      • DeepSeek — мой идеальный напарник. За четыре дня я с DeepSeek исправил более 20 ошибок. Без него я бы просто не справился.

      • Нельзя игнорировать внешние ограничения. Иногда проблема не в твоём коде, а в окружении. И это нужно принимать.

      • Перерыв — это не слабость. Это способ сохранить ясность ума и не потерять интерес.

      • Этот путь — долгий. И это нормально. Главное — идти вперёд, даже если с остановками.

      Итоговый статус

      • Код: полностью готов к работе.

      • SEO: все ошибки исправлены.

      • Контент: очищен, объёмный, структурированный.

      • Дубли: исключены.

      • Изображения: подгружаются из RSS.

      • Единственная проблема: хостинг блокирует доступ к RSS-источникам.

      Как только хостинг снимет ограничения, плагин заработает в полную силу. Но я не тороплюсь. Я сделаю перерыв, осмыслю всё, что сделал, и вернусь с новыми силами.

      Что дальше?

      Я напишу отдельный пост о решении проблемы с хостингом, когда оно появится. А пока — отдыхаю, читаю, вдохновляюсь. И ты делай так же, если чувствуешь, что устал.

      Призыв к действию

      Если ты тоже разрабатываешь что-то сложное — не забывай про себя. Не гонись за результатом любой ценой. Иногда лучший шаг вперёд — это шаг назад, чтобы разогнаться.

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

      Контакты

      📧 Email: milyutinkv@gmail.com
      🌐 Сайт: milyutin-codes.ru
      💬 Группа ВК: vk.ru/milyutin_codes

      Задавай вопросы, делись идеями, пиши свои истории. Мы вместе.

      Продолжение следует. Но сначала — пауза.

    Константин Милютин
    Создано с помощью нейросети Алисы YandexART для milyutin-codes.ru

    Константин Милютин
    Автор блога «Милютин Код»