Plugin Directory

Changeset 3765636


Ignore:
Timestamp:
10/26/2026 06:34:33 AM (31 hours ago)
Author:
mar4elo06
Message:

OGImg Covers 1.5.1

Location:
ogimg-covers
Files:
15 added
2 edited

Legend:

Unmodified
Added
Removed
  • ogimg-covers/trunk/ogimg-covers.php

    r3765592 r3765636  
    33 * Plugin Name:       OGImg Covers
    44 * Plugin URI:        https://og-studio.online/wp-plugin
    5  * Description:       Стильные OG-обложки для записей и страниц: заголовок и подзаголовок подставляются из записи, стиль — один из 32 шаблонов (те же, что в редакторе); «Фото-фон» и «Товар и цена» берут фото из «Изображения записи». Обложка уходит в og:image и twitter:image, для старых записей — пакетом в один клик. С ключом Про — без водяного знака.
    6  * Version:           1.5.0
     5 * Description:       Stylish OG covers for posts and pages: the title and subtitle come from the post, the style is one of 32 templates (the same as in the online editor); "Photo background" and "Product & price" use the post's featured image. The cover goes into og:image and twitter:image; covers for existing posts are generated in bulk in one click. With a Pro key - no watermark.
     6 * Version:           1.5.1
    77 * Author:            OGImg
    88 * Author URI:        https://og-studio.online
    … …  
    1010 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
    1111 * Text Domain:       ogimg-covers
     12 * Domain Path:       /languages
    1213 * Requires at least: 5.8
    1314 * Requires PHP:      7.4
    … …  
    1819}
    1920
    20 define('OGIMG_COVERS_VERSION', '1.5.0');
     21define('OGIMG_COVERS_VERSION', '1.5.1');
    2122defined('OGIMG_COVERS_RENDER_URL') || define('OGIMG_COVERS_RENDER_URL', 'https://og-studio.online/api/og/render.png');
    2223defined('OGIMG_COVERS_SHORTEN_URL') || define('OGIMG_COVERS_SHORTEN_URL', 'https://og-studio.online/api/og/shorten');
    … …  
    2425defined('OGIMG_COVERS_SHORT_PREFIX') || define('OGIMG_COVERS_SHORT_PREFIX', 'https://og-studio.online/img/');
    2526define('OGIMG_COVERS_OPTION', 'ogimg_covers_settings');
     27
     28/* ------------------------------------------------------------------ *
     29 * Переводы: исходные строки — английские, русский перевод лежит в
     30 * languages/ (подхватывается сразу, не дожидаясь языковых пакетов).
     31 * ------------------------------------------------------------------ */
     32
     33function ogimg_covers_load_textdomain()
     34{
     35    // phpcs:ignore PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound -- bundled ru_RU translation
     36    load_plugin_textdomain('ogimg-covers', false, dirname(plugin_basename(__FILE__)) . '/languages');
     37}
     38add_action('init', 'ogimg_covers_load_textdomain');
     39
     40/** Простой HTML, разрешённый в переводимых строках с разметкой. */
     41function ogimg_covers_allowed_html()
     42{
     43    return array(
     44        'a'      => array('href' => true, 'target' => true, 'rel' => true),
     45        'strong' => array('id' => true),
     46        'code'   => array(),
     47    );
     48}
    2649
    2750/* ------------------------------------------------------------------ *
    … …  
    6083{
    6184    return array(
    62         'sunset'        => 'Закат',
    63         'minimal'       => 'Минимал',
    64         'bold-black'    => 'Графит',
    65         'aurora'        => 'Сияние',
     85        'sunset'        => __('Sunset', 'ogimg-covers'),
     86        'minimal'       => __('Minimal', 'ogimg-covers'),
     87        'bold-black'    => __('Graphite', 'ogimg-covers'),
     88        'aurora'        => __('Aurora', 'ogimg-covers'),
    6689        // 1.4.0 (19.10.2026): фото — из «Изображения записи» (миниатюры)
    67         'image-overlay' => 'Фото-фон',
    68         'dots'          => 'Точки',
    69         'ocean'         => 'Океан',
    70         'forest'        => 'Лес',
    71         'royal'         => 'Королевский',
    72         'sunset-dark'   => 'Тёмный закат',
    73         'grid'          => 'Сетка',
    74         'gradient-mesh' => 'Пастель',
    75         'neon-frame'    => 'Неон-рамка',
    76         'accent-bar'    => 'Плашка',
    77         'diagonal'      => 'Диагонали',
    78         'underline'     => 'Линия',
    79         'duotone'       => 'Дуотон',
    80         'frame-inset'   => 'Паспарту',
    81         'blob'          => 'Круг',
    82         'wedge'         => 'Уголок',
    83         'autumn-amber'  => 'Осень',
    84         'autumn-dark'   => 'Тёмная осень',
    85         'winter-frost'  => 'Зима',
    86         'winter-night'  => 'Зимняя ночь',
     90        'image-overlay' => __('Photo background', 'ogimg-covers'),
     91        'dots'          => __('Dots', 'ogimg-covers'),
     92        'ocean'         => __('Ocean', 'ogimg-covers'),
     93        'forest'        => __('Forest', 'ogimg-covers'),
     94        'royal'         => __('Royal', 'ogimg-covers'),
     95        'sunset-dark'   => __('Dark sunset', 'ogimg-covers'),
     96        'grid'          => __('Grid', 'ogimg-covers'),
     97        'gradient-mesh' => __('Pastel', 'ogimg-covers'),
     98        'neon-frame'    => __('Neon frame', 'ogimg-covers'),
     99        'accent-bar'    => __('Accent bar', 'ogimg-covers'),
     100        'diagonal'      => __('Diagonals', 'ogimg-covers'),
     101        'underline'     => __('Underline', 'ogimg-covers'),
     102        'duotone'       => __('Duotone', 'ogimg-covers'),
     103        'frame-inset'   => __('Passepartout', 'ogimg-covers'),
     104        'blob'          => __('Circle', 'ogimg-covers'),
     105        'wedge'         => __('Corner', 'ogimg-covers'),
     106        'autumn-amber'  => __('Autumn', 'ogimg-covers'),
     107        'autumn-dark'   => __('Dark autumn', 'ogimg-covers'),
     108        'winter-frost'  => __('Winter', 'ogimg-covers'),
     109        'winter-night'  => __('Winter night', 'ogimg-covers'),
    87110        // 1.3.0 (17.10.2026): шаблоны «под задачу» — доп. поля берутся из макета
    88         'article'       => 'Статья блога',
    89         'event'         => 'Вебинар / событие',
    90         'quote'         => 'Цитата',
    91         'stat'          => 'Цифра',
    92         'product'       => 'Товар и цена',
    93         'job'           => 'Вакансия',
    94         'podcast'       => 'Подкаст / эпизод',
    95         'list'          => 'Список пунктов',
    96         'halloween'     => 'Хэллоуин',
    97         'black-friday'  => 'Чёрная пятница',
    98         'new-year'      => 'Новый год',
     111        'article'       => __('Blog article', 'ogimg-covers'),
     112        'event'         => __('Webinar / event', 'ogimg-covers'),
     113        'quote'         => __('Quote', 'ogimg-covers'),
     114        'stat'          => __('Big number', 'ogimg-covers'),
     115        'product'       => __('Product & price', 'ogimg-covers'),
     116        'job'           => __('Job opening', 'ogimg-covers'),
     117        'podcast'       => __('Podcast / episode', 'ogimg-covers'),
     118        'list'          => __('List', 'ogimg-covers'),
     119        'halloween'     => __('Halloween', 'ogimg-covers'),
     120        'black-friday'  => __('Black Friday', 'ogimg-covers'),
     121        'new-year'      => __('New Year', 'ogimg-covers'),
    99122    );
    100123}
    … …  
    140163{
    141164    return array(
    142         'og'             => 'OG-картинка · 1200×630',
    143         'square'         => 'Квадрат · 1080×1080',
    144         'story'          => 'Сторис · 1080×1920',
    145         'twitter-banner' => 'Баннер X/Twitter · 1500×500',
    146         'wide-16-9'      => 'Широкая 16:9 · 1280×720',
     165        'og'             => __('OG image · 1200×630', 'ogimg-covers'),
     166        'square'         => __('Square · 1080×1080', 'ogimg-covers'),
     167        'story'          => __('Story · 1080×1920', 'ogimg-covers'),
     168        'twitter-banner' => __('X/Twitter banner · 1500×500', 'ogimg-covers'),
     169        'wide-16-9'      => __('Wide 16:9 · 1280×720', 'ogimg-covers'),
    147170    );
    148171}
    … …  
    151174{
    152175    return array(
    153         ''      => 'Точка (стандарт)',
    154         'star'  => 'Звезда',
    155         'heart' => 'Сердце',
    156         'bolt'  => 'Молния',
    157         'spark' => 'Искра',
     176        ''      => __('Dot (default)', 'ogimg-covers'),
     177        'star'  => __('Star', 'ogimg-covers'),
     178        'heart' => __('Heart', 'ogimg-covers'),
     179        'bolt'  => __('Bolt', 'ogimg-covers'),
     180        'spark' => __('Spark', 'ogimg-covers'),
    158181    );
    159182}
    … …  
    224247
    225248add_action('admin_menu', function () {
    226     add_options_page('OGImg Covers', 'OGImg Covers', 'manage_options', 'ogimg-covers', 'ogimg_covers_render_settings_page');
     249    add_options_page(__('OGImg Covers', 'ogimg-covers'), __('OGImg Covers', 'ogimg-covers'), 'manage_options', 'ogimg-covers', 'ogimg_covers_render_settings_page');
    227250    add_management_page(
    228         'OGImg Covers — обложки для старых записей',
    229         'OGImg Covers',
     251        __('OGImg Covers — covers for existing posts', 'ogimg-covers'),
     252        __('OGImg Covers', 'ogimg-covers'),
    230253        'manage_options',
    231254        'ogimg-covers-bulk',
    … …  
    237260    array_unshift(
    238261        $links,
    239         '<a href="' . esc_url(admin_url('options-general.php?page=ogimg-covers')) . '">Настройки</a>',
    240         '<a href="' . esc_url(admin_url('tools.php?page=ogimg-covers-bulk')) . '">Старые записи</a>'
     262        '<a href="' . esc_url(admin_url('options-general.php?page=ogimg-covers')) . '">' . esc_html__('Settings', 'ogimg-covers') . '</a>',
     263        '<a href="' . esc_url(admin_url('tools.php?page=ogimg-covers-bulk')) . '">' . esc_html__('Existing posts', 'ogimg-covers') . '</a>'
    241264    );
    242265    return $links;
    … …  
    271294    $status = $s['pro_key'] !== '' ? ogimg_covers_check_key($s['pro_key']) : '';
    272295    $labels = array(
    273         'ok'      => array('#008a20', 'Ключ работает: новые обложки — без водяного знака.'),
    274         'not_pro' => array('#b26200', 'Ключ верный, но подписка Про не активна — обложки с водяным знаком.'),
    275         'invalid' => array('#d63638', 'Ключ не найден. Выпусти новый на og-studio.online/wp-plugin.'),
    276         'offline' => array('#646970', 'Сервис сейчас недоступен — проверим позже.'),
     296        'ok'      => array('#008a20', __('The key works: new covers have no watermark.', 'ogimg-covers')),
     297        'not_pro' => array('#b26200', __('The key is valid, but the Pro subscription is not active — covers have a watermark.', 'ogimg-covers')),
     298        'invalid' => array('#d63638', __('Key not found. Get a new one at og-studio.online/wp-plugin.', 'ogimg-covers')),
     299        'offline' => array('#646970', __('The service is unavailable right now — we will check later.', 'ogimg-covers')),
    277300    );
    278301    ?>
    279302    <div class="wrap">
    280         <h1>OGImg Covers — настройки</h1>
     303        <h1><?php esc_html_e('OGImg Covers — settings', 'ogimg-covers'); ?></h1>
    281304        <form method="post" action="options.php">
    282305            <?php settings_fields('ogimg_covers'); ?>
    283306            <table class="form-table" role="presentation">
    284307                <tr>
    285                     <th scope="row"><label for="og_pro_key">Ключ Про</label></th>
     308                    <th scope="row"><label for="og_pro_key"><?php esc_html_e('Pro key', 'ogimg-covers'); ?></label></th>
    286309                    <td>
    287310                        <input type="text" id="og_pro_key" class="regular-text code" autocomplete="off"
    … …  
    294317                        <?php endif; ?>
    295318                        <p class="description">
    296                             Для подписчиков Про: обложки без плашки og-studio.online. Ключ выпускается на
    297                             <a href="https://og-studio.online/wp-plugin" target="_blank" rel="noopener">og-studio.online/wp-plugin</a>.
    298                             Ключ уходит только на сервис OG Studio при получении короткой ссылки и на страницах сайта не виден.
     319                            <?php
     320                            echo wp_kses(
     321                                sprintf(
     322                                    /* translators: %s: link to the og-studio.online/wp-plugin page */
     323                                    __('For Pro subscribers: covers without the og-studio.online label. Get a key at %s. The key is sent only to the OG Studio service when a short link is requested and is never visible on your site pages.', 'ogimg-covers'),
     324                                    '<a href="https://og-studio.online/wp-plugin" target="_blank" rel="noopener">og-studio.online/wp-plugin</a>'
     325                                ),
     326                                ogimg_covers_allowed_html()
     327                            );
     328                            ?>
    299329                        </p>
    300330                    </td>
    301331                </tr>
    302332                <tr>
    303                     <th scope="row">Стиль по умолчанию</th>
     333                    <th scope="row"><?php esc_html_e('Default style', 'ogimg-covers'); ?></th>
    304334                    <td>
    305335                        <?php ogimg_covers_style_fields(OGIMG_COVERS_OPTION, $s, 'og_def'); ?>
    306                         <p class="description">Подставляется в новые записи и при пакетной генерации для старых.</p>
     336                        <p class="description"><?php esc_html_e('Applied to new posts and to bulk generation for existing posts.', 'ogimg-covers'); ?></p>
    307337                    </td>
    308338                </tr>
    309339                <tr>
    310                     <th scope="row">Новые записи</th>
     340                    <th scope="row"><?php esc_html_e('New posts', 'ogimg-covers'); ?></th>
    311341                    <td>
    312342                        <label>
    313343                            <input type="checkbox" name="<?php echo esc_attr(OGIMG_COVERS_OPTION); ?>[auto_enable]" value="1" <?php checked($s['auto_enable'], '1'); ?> />
    314                             сразу включать обложку (галочку «og:image») в новых записях
     344                            <?php esc_html_e('Enable the cover (the "og:image" checkbox) right away in new posts', 'ogimg-covers'); ?>
    315345                        </label>
    316346                    </td>
    317347                </tr>
    318348            </table>
    319             <?php submit_button('Сохранить'); ?>
     349            <?php submit_button(__('Save changes', 'ogimg-covers')); ?>
    320350        </form>
    321351        <p>
    322             Обложки для уже опубликованных записей —
    323             <a href="<?php echo esc_url(admin_url('tools.php?page=ogimg-covers-bulk')); ?>">Инструменты → OGImg Covers</a>.
     352            <?php
     353            echo wp_kses(
     354                sprintf(
     355                    /* translators: %s: link to the Tools → OGImg Covers page */
     356                    __('Covers for posts that are already published: %s.', 'ogimg-covers'),
     357                    '<a href="' . esc_url(admin_url('tools.php?page=ogimg-covers-bulk')) . '">' . esc_html__('Tools → OGImg Covers', 'ogimg-covers') . '</a>'
     358                ),
     359                ogimg_covers_allowed_html()
     360            );
     361            ?>
    324362        </p>
    325363    </div>
    … …  
    332370    $tpls = ogimg_covers_templates($cfg['template']);
    333371    $fields = array(
    334         'template' => array('Шаблон', $tpls),
    335         'badge'    => array('Значок', ogimg_covers_badges()),
    336         'format'   => array('Формат', ogimg_covers_formats()),
     372        'template' => array(__('Template', 'ogimg-covers'), $tpls),
     373        'badge'    => array(__('Badge', 'ogimg-covers'), ogimg_covers_badges()),
     374        'format'   => array(__('Format', 'ogimg-covers'), ogimg_covers_formats()),
    337375    );
    338376    foreach ($fields as $field => $def) {
    … …  
    350388            ?>
    351389            <p>
    352                 <label for="<?php echo esc_attr($id_prefix . '_accent'); ?>" style="display:inline-block;min-width:80px;">Акцент</label>
     390                <label for="<?php echo esc_attr($id_prefix . '_accent'); ?>" style="display:inline-block;min-width:80px;"><?php esc_html_e('Accent', 'ogimg-covers'); ?></label>
    353391                <input type="color" id="<?php echo esc_attr($id_prefix . '_accent'); ?>" name="<?php echo esc_attr($name . '[accent]'); ?>" value="<?php echo esc_attr($cfg['accent']); ?>" />
    354392            </p>
    … …  
    539577    add_meta_box(
    540578        'ogimg_covers_box',
    541         'OGImg Covers — обложка записи',
     579        __('OGImg Covers — post cover', 'ogimg-covers'),
    542580        'ogimg_covers_render_metabox',
    543581        array('post', 'page'),
    … …  
    620658    <div class="ogimg-covers-box" data-og-photo="<?php echo esc_attr($cfg['photo'] ?? ''); ?>">
    621659        <div class="og-field">
    622             <label for="og_title">Заголовок</label>
     660            <label for="og_title"><?php esc_html_e('Title', 'ogimg-covers'); ?></label>
    623661            <input type="text" id="og_title" name="ogimg_covers_title" value="<?php echo esc_attr($cfg['title']); ?>" />
    624             <p class="og-hint">По умолчанию — название записи. До 200 знаков; длинный сам уменьшится.</p>
     662            <p class="og-hint"><?php esc_html_e('Defaults to the post title. Up to 200 characters; a long title shrinks automatically.', 'ogimg-covers'); ?></p>
    625663        </div>
    626664        <div class="og-field">
    627             <label for="og_subtitle">Подзаголовок</label>
     665            <label for="og_subtitle"><?php esc_html_e('Subtitle', 'ogimg-covers'); ?></label>
    628666            <input type="text" id="og_subtitle" name="ogimg_covers_subtitle" value="<?php echo esc_attr($cfg['subtitle']); ?>" />
    629             <p class="og-hint">По умолчанию — цитата (excerpt) записи. Можно оставить пустым.</p>
     667            <p class="og-hint"><?php esc_html_e('Defaults to the post excerpt. Can be left empty.', 'ogimg-covers'); ?></p>
    630668        </div>
    631669        <div class="og-field">
    632             <label for="og_brand">Бренд</label>
     670            <label for="og_brand"><?php esc_html_e('Brand', 'ogimg-covers'); ?></label>
    633671            <input type="text" id="og_brand" name="ogimg_covers_brand" value="<?php echo esc_attr($cfg['brand']); ?>" />
    634             <p class="og-hint">Короткая подпись-чип в углу. По умолчанию — название сайта.</p>
     672            <p class="og-hint"><?php esc_html_e('A short chip label in the corner. Defaults to the site name.', 'ogimg-covers'); ?></p>
    635673        </div>
    636674        <div class="og-field">
    637             <label for="og_template">Шаблон</label>
     675            <label for="og_template"><?php esc_html_e('Template', 'ogimg-covers'); ?></label>
    638676            <select id="og_template" name="ogimg_covers_template">
    639677                <?php foreach ($tpls as $key => $label) : ?>
    … …  
    641679                <?php endforeach; ?>
    642680            </select>
    643             <p class="og-hint">Праздничные шаблоны (Хэллоуин, Чёрная пятница, Новый год) появляются в дни праздника.
    644                 «Фото-фон» и «Товар и цена» берут фото из «Изображения записи» (нужна ссылка https://)<?php
    645                 echo empty($cfg['photo']) ? ' — у этой записи его пока нет, обложка будет без фото.' : '.'; ?></p>
     681            <p class="og-hint"><?php
     682                if (empty($cfg['photo'])) {
     683                    esc_html_e('Holiday templates (Halloween, Black Friday, New Year) appear on the holiday dates. "Photo background" and "Product & price" use the post\'s featured image (an https:// link is required) — this post has none yet, so the cover will be drawn without a photo.', 'ogimg-covers');
     684                } else {
     685                    esc_html_e('Holiday templates (Halloween, Black Friday, New Year) appear on the holiday dates. "Photo background" and "Product & price" use the post\'s featured image (an https:// link is required).', 'ogimg-covers');
     686                }
     687            ?></p>
    646688        </div>
    647689        <div class="og-field">
    648             <label for="og_accent">Акцент</label>
     690            <label for="og_accent"><?php esc_html_e('Accent', 'ogimg-covers'); ?></label>
    649691            <input type="color" id="og_accent" name="ogimg_covers_accent" value="<?php echo esc_attr($cfg['accent']); ?>" />
    650692        </div>
    651693        <div class="og-field">
    652             <label for="og_badge">Значок</label>
     694            <label for="og_badge"><?php esc_html_e('Badge', 'ogimg-covers'); ?></label>
    653695            <select id="og_badge" name="ogimg_covers_badge">
    654696                <?php foreach ($bdgs as $key => $label) : ?>
    … …  
    658700        </div>
    659701        <div class="og-field">
    660             <label for="og_format">Формат</label>
     702            <label for="og_format"><?php esc_html_e('Format', 'ogimg-covers'); ?></label>
    661703            <select id="og_format" name="ogimg_covers_format">
    662704                <?php foreach ($fmts as $key => $label) : ?>
    … …  
    668710            <label for="og_enabled">og:image</label>
    669711            <input type="checkbox" id="og_enabled" name="ogimg_covers_enabled" value="1" <?php checked($cfg['enabled']); ?> />
    670             подставлять эту обложку в &lt;meta property="og:image"&gt; на странице записи
     712            <?php esc_html_e('use this cover in <meta property="og:image"> on the post page', 'ogimg-covers'); ?>
    671713        </div>
    672714
    673715        <div class="og-preview">
    674             <img id="og_preview" src="<?php echo esc_url(ogimg_covers_build_url($cfg)); ?>" alt="Предпросмотр обложки OGImg Covers" />
     716            <img id="og_preview" src="<?php echo esc_url(ogimg_covers_build_url($cfg)); ?>" alt="<?php esc_attr_e('OGImg Covers cover preview', 'ogimg-covers'); ?>" />
    675717        </div>
    676718        <div class="og-url-row">
    677719            <input type="text" id="og_url" readonly value="<?php echo esc_attr($url); ?>" />
    678             <button type="button" class="button" id="og_refresh">Обновить превью</button>
    679             <button type="button" class="button" id="og_copy">Копировать URL</button>
     720            <button type="button" class="button" id="og_refresh"><?php esc_html_e('Refresh preview', 'ogimg-covers'); ?></button>
     721            <button type="button" class="button" id="og_copy"><?php esc_html_e('Copy URL', 'ogimg-covers'); ?></button>
    680722        </div>
    681723        <p class="og-hint" style="margin-left:0;">
    682             Обложку можно вставить в og:image (галочка выше), в текст записи шорткодом <code>[ogimg_covers_cover]</code>
    683             или в любое поле «картинка для соцсетей». После сохранения записи плагин получает
    684             <strong>короткую ссылку</strong> вида <code>og-studio.online/img/Ab3xKp9f</code>.
     724            <?php
     725            echo wp_kses(
     726                __('You can use the cover as og:image (checkbox above), insert it into the post text with the <code>[ogimg_covers_cover]</code> shortcode, or paste it into any "social image" field. After the post is saved, the plugin gets a <strong>short link</strong> like <code>og-studio.online/img/Ab3xKp9f</code>.', 'ogimg-covers'),
     727                ogimg_covers_allowed_html()
     728            );
     729            ?>
    685730            <?php if ($s['pro_key'] !== '') : ?>
    686                 С ключом Про короткая ссылка — без водяного знака (в превью он остаётся).
     731                <?php esc_html_e('With a Pro key the short link has no watermark (the preview still shows it).', 'ogimg-covers'); ?>
    687732            <?php endif; ?>
    688733        </p>
    … …  
    783828    ?>
    784829    <div class="wrap">
    785         <h1>OGImg Covers — обложки для старых записей</h1>
     830        <h1><?php esc_html_e('OGImg Covers — covers for existing posts', 'ogimg-covers'); ?></h1>
    786831        <p>
    787             Плагин создаст обложки для опубликованных записей, где обложки OGImg Covers ещё нет: заголовок и цитата —
    788             из записи, стиль — <strong><?php echo esc_html($tpls[$s['template']] ?? 'Закат'); ?></strong>
    789             (меняется в <a href="<?php echo esc_url(admin_url('options-general.php?page=ogimg-covers')); ?>">настройках</a>).
    790             Обложка сразу попадёт в og:image. Записи, где ты уже настраивал обложку, не трогаем.
    791         </p>
    792         <p>Записей без обложки: <strong id="og_bulk_count"><?php echo (int) $count; ?></strong>.</p>
    793         <p>
    794             <label><input type="checkbox" id="og_bulk_pages" /> и страницы тоже</label><br />
    795             <label><input type="checkbox" id="og_bulk_skip_thumb" /> пропускать записи, у которых есть своя миниатюра</label>
     832            <?php
     833            echo wp_kses(
     834                sprintf(
     835                    /* translators: 1: template name, 2: URL of the plugin settings page */
     836                    __('The plugin will create covers for published posts that do not have an OGImg Covers cover yet: the title and excerpt come from the post, the style is <strong>%1$s</strong> (change it in the <a href="%2$s">settings</a>). The cover goes into og:image right away. Posts whose cover you have already set up are left untouched.', 'ogimg-covers'),
     837                    esc_html($tpls[$s['template']] ?? __('Sunset', 'ogimg-covers')),
     838                    esc_url(admin_url('options-general.php?page=ogimg-covers'))
     839                ),
     840                ogimg_covers_allowed_html()
     841            );
     842            ?>
    796843        </p>
    797844        <p>
    798             <button type="button" class="button button-primary" id="og_bulk_start">Создать обложки</button>
    799             <button type="button" class="button" id="og_bulk_stop" disabled>Остановить</button>
     845            <?php
     846            echo wp_kses(
     847                sprintf(
     848                    /* translators: %s: number of posts without a cover (wrapped in <strong>) */
     849                    _n('%s post has no cover yet.', '%s posts have no cover yet.', (int) $count, 'ogimg-covers'),
     850                    '<strong id="og_bulk_count">' . (int) $count . '</strong>'
     851                ),
     852                ogimg_covers_allowed_html()
     853            );
     854            ?>
     855        </p>
     856        <p>
     857            <label><input type="checkbox" id="og_bulk_pages" /> <?php esc_html_e('include pages too', 'ogimg-covers'); ?></label><br />
     858            <label><input type="checkbox" id="og_bulk_skip_thumb" /> <?php esc_html_e('skip posts that have their own featured image', 'ogimg-covers'); ?></label>
     859        </p>
     860        <p>
     861            <button type="button" class="button button-primary" id="og_bulk_start"><?php esc_html_e('Create covers', 'ogimg-covers'); ?></button>
     862            <button type="button" class="button" id="og_bulk_stop" disabled><?php esc_html_e('Stop', 'ogimg-covers'); ?></button>
    800863        </p>
    801864        <div style="max-width:520px;height:12px;background:#dcdcde;border-radius:6px;overflow:hidden;">
    … …  
    816879        var ajax = ' . wp_json_encode(admin_url('admin-ajax.php')) . ';
    817880        var nonce = ' . wp_json_encode(wp_create_nonce('ogimg_covers_bulk')) . ';
     881        var i18n = ' . wp_json_encode(array(
     882            /* translators: 1: posts processed so far, 2: total posts */
     883            'stopped'  => __('Stopped: %1$d of %2$d done.', 'ogimg-covers'),
     884            /* translators: 1: posts processed so far, 2: total posts */
     885            'progress' => __('Done %1$d of %2$d…', 'ogimg-covers'),
     886            /* translators: %1$d: number of posts processed */
     887            'finished' => __('Done. Posts processed: %1$d.', 'ogimg-covers'),
     888            /* translators: %1$d: number of posts processed so far */
     889            'netError' => __('Connection error. Processed: %1$d — click again to continue.', 'ogimg-covers'),
     890            'counting' => __('Counting posts…', 'ogimg-covers'),
     891            'allDone'  => __('All posts already have covers.', 'ogimg-covers'),
     892            'retry'    => __('Connection error — please try again.', 'ogimg-covers'),
     893        )) . ';
     894        function fmt(text, a, b) { return text.replace(\'%1$d\', a).replace(\'%2$d\', b); }
    818895        var start = document.getElementById(\'og_bulk_start\');
    819896        var stop = document.getElementById(\'og_bulk_stop\');
    … …  
    834911        }
    835912        function step() {
    836             if (!running) { status.textContent = \'Остановлено: готово \' + done + \' из \' + total + \'.\'; return; }
     913            if (!running) { status.textContent = fmt(i18n.stopped, done, total); return; }
    837914            post(\'ogimg_covers_bulk_step\').then(function (res) {
    838915                if (!res || !res.success) { throw new Error(\'step\'); }
    839916                done += res.data.processed;
    840917                bar.style.width = (total ? Math.min(100, Math.round(done / total * 100)) : 100) + \'%\';
    841                 status.textContent = \'Готово \' + done + \' из \' + total + \'…\';
     918                status.textContent = fmt(i18n.progress, done, total);
    842919                if (res.data.left > 0 && res.data.processed > 0) { setTimeout(step, 300); }
    843                 else { finish(\'Готово: обложки созданы для \' + done + \' записей.\'); }
    844             }).catch(function () { finish(\'Ошибка связи. Обработано \' + done + \' — нажми ещё раз, чтобы продолжить.\'); });
     920                else { finish(fmt(i18n.finished, done, total)); }
     921            }).catch(function () { finish(fmt(i18n.netError, done, total)); });
    845922        }
    846923        function finish(text) {
    … …  
    849926        }
    850927        start.addEventListener(\'click\', function () {
    851             start.disabled = true; stop.disabled = false; status.textContent = \'Считаем записи…\';
     928            start.disabled = true; stop.disabled = false; status.textContent = i18n.counting;
    852929            post(\'ogimg_covers_bulk_count\').then(function (res) {
    853930                total = res && res.success ? res.data.count : 0; done = 0;
    854                 if (!total) { finish(\'Все записи уже с обложками.\'); return; }
     931                if (!total) { finish(i18n.allDone); return; }
    855932                running = true; step();
    856             }).catch(function () { finish(\'Ошибка связи — попробуй ещё раз.\'); });
     933            }).catch(function () { finish(i18n.retry); });
    857934        });
    858935        stop.addEventListener(\'click\', function () { running = false; stop.disabled = true; });
    … …  
    9271004    $url  = ogimg_covers_resolve_url($cfg);
    9281005    $dims = ogimg_covers_dims($cfg['format']);
    929     echo "\n<!-- OGImg Covers: обложка записи -->\n";
     1006    echo "\n<!-- OGImg Covers: post cover -->\n";
    9301007    printf('<meta property="og:image" content="%s" />' . "\n", esc_url($url));
    9311008    printf('<meta property="og:image:width" content="%d" />' . "\n", (int) $dims[0]);
  • ogimg-covers/trunk/readme.txt

    r3765592 r3765636  
    55Tested up to: 7.1
    66Requires PHP: 7.4
    7 Stable tag: 1.5.0
     7Stable tag: 1.5.1
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    7777== Changelog ==
    7878
     79= 1.5.1 =
     80* Interface is now fully translatable (English source strings); Russian translation included.
     81
    7982= 1.5.0 =
    8083* Plugin renamed to OGImg Covers (new slug ogimg-covers); settings and per-post data are migrated automatically.
    … …  
    106109== Upgrade Notice ==
    107110
     111= 1.5.1 =
     112Interface is now fully translatable (English source strings); Russian translation included.
     113
    108114= 1.5.0 =
    109115Plugin renamed to OGImg Covers. Settings and per-post data are migrated automatically.
Note: See TracChangeset for help on using the changeset viewer.