Skip to content

Примеры Custom Containers

Ниже - чистые примеры конфигов для типовых клиентских сценариев.

1. Баннер с заменой по маркеру

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

ts
const bannerContainer = {
  id: 'banner',
  name: 'Баннер',
  toolIcon: '<svg viewBox="0 0 16 16"><path d="M2 5h12v6H2z" /></svg>',
  width: 970,
  height: 250,
  resizable: false,
  dummyImageUrl: null,
  html: '',
  replaceMarker: 'banner',
  attributes: {
    slot: 'banner',
    placement: 'top'
  },
  customProps: {},
  tool: {
    sectionsConfig: {},
    controlsConfig: {}
  }
}

В итоговом HTML останется сам контейнер и маркер для замены. Визуальная заглушка в превью и на сайте клиента не рендерится:

html
<!-- ReplaceMarker: banner -->

Пример замены на PHP:

php
$articleHtml = str_replace(
    '<!-- ReplaceMarker: banner -->',
    renderBannerWidget($article, 'top'),
    $articleHtml
);

2. Авторы статьи как готовый HTML

Если клиентская админка уже знает авторов статьи, конфиг можно собрать сразу с реальным HTML.

ts
const articleAuthorsContainer = {
  id: 'article-authors',
  name: 'Авторы',
  toolIcon:
    '<svg viewBox="0 0 16 16"><path d="M6.5 7a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zM1.75 13.5c.45-2.5 2.2-4 4.75-4s4.3 1.5 4.75 4z" /></svg>',
  width: 320,
  height: 72,
  resizable: true,
  dummyImageUrl: null,
  html: `
    <style>
      .client-authors {
        display: flex;
        gap: 12px;
        align-items: center;
        width: 100%;
        height: 100%;
        font: 14px/1.35 Arial, sans-serif;
      }

      .client-author {
        display: inline-flex;
        gap: 8px;
        align-items: center;
        color: inherit;
        text-decoration: none;
      }

      .client-author img {
        width: 36px;
        height: 36px;
        border-radius: 50%;
        object-fit: cover;
      }

      .client-author small {
        display: block;
        color: #6b7280;
      }
    </style>

    <div class="client-authors">
      <a class="client-author" href="/authors/anna-smirnova">
        <img src="https://client-cdn.example/authors/anna.jpg" alt="" />
        <span>
          <strong>Анна Смирнова</strong>
          <small>Автор</small>
        </span>
      </a>

      <a class="client-author" href="/authors/ivan-petrov">
        <img src="https://client-cdn.example/authors/ivan.jpg" alt="" />
        <span>
          <strong>Иван Петров</strong>
          <small>Редактор</small>
        </span>
      </a>
    </div>
  `,
  replaceMarker: null,
  attributes: {
    slot: 'authors'
  },
  customProps: {},
  tool: {
    sectionsConfig: {},
    controlsConfig: {}
  }
}

Такой контейнер не требует замены по маркеру: HTML уже содержит актуальных авторов.

3. Кнопка "Купить" с HTML, CSS и настройками

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

Контролы не интерполируют значения обратно в html автоматически. Они сохраняют значения в customProps, а итоговый HTML получает параметры контейнера. Клиентская замена или JS-инициализация может прочитать эти параметры и построить финальную кнопку.

ts
const buyButtonContainer = {
  id: 'buy-button',
  name: 'Купить',
  toolIcon: '<svg viewBox="0 0 16 16"><path d="M3 4h10l-1 6H5zM5 4 6 2h4l1 2M6 13h.01M11 13h.01" /></svg>',
  width: 180,
  height: 44,
  resizable: true,
  dummyImageUrl: null,
  html: `
    <style>
      .client-buy-button {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 100%;
        border-radius: 6px;
        background: #111827;
        color: #ffffff;
        font: 600 15px/1 Arial, sans-serif;
        text-decoration: none;
      }
    </style>
    <a class="client-buy-button" data-client-buy-button href="#">Купить</a>
  `,
  replaceMarker: 'buy-button',
  attributes: {
    slot: 'commerce'
  },
  customProps: {
    productId: '',
    label: 'Купить',
    theme: 'dark',
    size: 'medium',
    openInNewTab: false
  },
  tool: {
    sectionsConfig: {
      CustomContainerSection: {
        widgetProperties: ['productId', 'label', 'theme', 'size', 'openInNewTab']
      }
    },
    controlsConfig: {
      productId: {
        type: 'TextInput',
        params: {
          label: 'Product ID',
          placeholder: 'sku-123'
        }
      },
      label: {
        type: 'TextInput',
        params: {
          label: 'Button text',
          placeholder: 'Купить'
        }
      },
      theme: {
        type: 'Tabs',
        params: {
          label: 'Theme',
          options: [
            { id: 'dark', label: 'Dark' },
            { id: 'light', label: 'Light' },
            { id: 'brand', label: 'Brand' }
          ],
          variant: 'secondary'
        }
      },
      size: {
        type: 'Tabs',
        params: {
          label: 'Size',
          options: [
            { id: 'small', label: 'S' },
            { id: 'medium', label: 'M' },
            { id: 'large', label: 'L' }
          ],
          variant: 'secondary'
        }
      },
      openInNewTab: {
        type: 'Toggle',
        params: {
          label: 'Open in new tab'
        }
      }
    }
  }
}

После редактирования параметры будут доступны в HTML контейнера как data-vrstk-custom-param-product-id, data-vrstk-custom-param-label, data-vrstk-custom-param-theme и так далее.