Amazon шаблон (HTML, CSS, JS) для интеграции. Руководство.

Инструкция для начинающих веб-разработчиков и пользователей Cotonti CMF, которые хотят создать современную, адаптивную шапку сайта с несколькими выезжающими (offcanvas) меню как в Amazon.

Рейтинг на основе отзывов:
Звезд получено: 0
Oтзывов всего: 0
Средняя оценка: 0
Опубликовано в: Блог пользователей

Подробное руководство по созданию адаптивной навигации с выезжающими меню (Amazon-like header)

Введение

Эта статья — подробное руководство для начинающих веб-разработчиков и пользователей Cotonti CMF, которые хотят создать современную, адаптивную шапку сайта с несколькими выезжающими (offcanvas) меню. В качестве примера мы будем разбирать готовый шаблон, имитирующий навигацию популярного интернет-магазина Amazon. Вы узнаете, как работают три независимых боковых меню (два слева и одно справа), как они свёрстаны с помощью HTML и CSS, и как управляются с помощью JavaScript. Все файлы (HTML, CSS, JS) выложены отдельно и готовы к использованию в ваших проектах.

Данный материал носит исключительно образовательный характер. Вы можете свободно брать этот код за основу, модифицировать его и интегрировать в свои темы для Cotonti CMF или любых других CMS. Мы последовательно, шаг за шагом, разберём каждый блок кода, объясним «что за чем стоит и почему», чтобы у вас сложилась целостная картина.


1. Обзор проекта и файловая структура

Перед нами три файла:

  • index.html — разметка страницы.
  • style.css — все стили.
  • script.js — логика работы меню.

Это классический подход, который позволяет разделить структуру, оформление и поведение. HTML остаётся чистым, в нём нет ни строчек CSS, ни скриптов (кроме подключения внешних библиотек). Такой код проще поддерживать и изменять.

В проекте используются две внешние библиотеки:

  • Bootstrap 5.3.2 (CSS и JS) — только для сетки, некоторых компонентов и иконок.
  • Font Awesome 6 — для иконок (стрелки, корзина, гамбургер и т.д.).

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

Теперь перейдём к самому главному — как это всё устроено.


2. HTML: каркас страницы и расположение элементов

HTML-документ представляет собой типичную структуру современного сайта. Он состоит из нескольких основных блоков:

  • Верхняя строка (.top-line) — логотип, поиск, иконки аккаунта, заказов и корзины.
  • Нижняя строка (.nav-line) — кнопка All и навигационные ссылки (Today's Deals, Customer Service и т.д.).
  • Три независимых offcanvas-меню с оверлеями.
  • Основной контент (заглушка).
  • Футер.

Разберём каждый блок детально.

2.1. Шапка: верхняя строка .top-line

<div class="top-line">
  <a href="/" class="logo"><span>A</span>mazon</a>
  <div class="search-box">
    <select><option>All</option><option>Books</option></select>
    <select><option>All Departments</option><option>Arts & Crafts</option></select>
    <input type="text" placeholder="Search Amazon">
    <button><i class="fas fa-search"></i></button>
  </div>
  <div class="header-icons">
    <a href="#" id="accountListsLink"><span>Hello, sign in</span><strong>Account & Lists</strong></a>
    <a href="#"><span>Returns</span><strong>& Orders</strong></a>
    <a href="#" class="cart-icon"><i class="fas fa-shopping-cart"></i><span class="cart-count">0</span></a>
  </div>
</div>

Здесь три дочерних элемента, расположенных в строку благодаря display: flex на .top-line.

Логотип — простая ссылка с классом .logo. Буква "A" обёрнута в <span>, чтобы её можно было стилизовать отдельно (жёлтый цвет). Сам логотип прижат к левому краю.

Поисковая строка — блок .search-box, который занимает всё доступное пространство благодаря flex: 1. Он содержит два выпадающих списка (категории), текстовое поле и кнопку. Внешняя рамка жёлтая, чтобы соответствовать стилю Amazon.

Иконки пользователя — ещё один flex-контейнер .header-icons с тремя элементами. Первая ссылка Account & Lists имеет идентификатор accountListsLink, который позже используется в JavaScript для открытия правого меню. Две другие ссылки пока никуда не ведут, но в реальном проекте будут направлять на соответствующие страницы. Иконка корзины содержит счётчик товаров (пока 0).

Важный момент: вся шапка оборачивается в flex-строку, и при нехватке места (например, на планшетах) элементы могут переноситься на новую строку благодаря flex-wrap: wrap.

2.2. Нижняя навигационная строка .nav-line

<div class="nav-line">
  <button class="mobile-nav-toggle" id="mobileNavToggle"><i class="fas fa-bars"></i></button>
  <button class="all-btn" id="allBtn"><i class="fas fa-bars"></i> All</button>
  <div class="nav-links" id="navLinks">
    <a href="#">Today's Deals</a>
    <a href="#">Customer Service</a>
    <a href="#">Gift Cards</a>
    <a href="#" id="helpSettingsLink">Help & Settings</a>
  </div>
</div>

Этот блок тоже flex-контейнер, и в нём три составляющих:

  • Кнопка-гамбургер .mobile-nav-toggle — показывается только на мобильных устройствах (через медиазапрос). Служит для открытия мобильного меню (набора ссылок navLinks). На десктопах скрыта (display: none).
  • Кнопка "All" — главный элемент, открывающий левое offcanvas-меню магазина. Имеет жёлтый фон и иконку "бургера". Обработчик клика привязан к #allBtn.
  • Навигационные ссылки — обёрнуты в #navLinks. На десктопе они отображаются в строку, на мобильных скрываются и выпадают вертикальным списком при клике на гамбургер. Ссылка "Help & Settings" имеет id="helpSettingsLink", чтобы её можно было найти в скрипте и открыть второе левое меню.

Таким образом, у нас есть два способа навигации: через кнопку All (каталог товаров) и через текстовые ссылки (помощь и настройки).

2.3. Система offcanvas-меню и оверлеев

Всего в документе три offcanvas-меню и три оверлея:

  1. Магазин (кнопка "All") — левое меню.
  2. Help & Settings — левое меню.
  3. Account & Lists — правое меню.

Для каждого из них создан свой оверлей (полупрозрачный фон) и контейнер самого меню. Оверлей и меню располагаются прямо в <body> до основного контента, но могут быть размещены и в конце — это не принципиально, так как они позиционированы фиксированно.

Рассмотрим на примере первого меню:

<div class="offcanvas-overlay" id="overlay-shop"></div>
<div class="offcanvas-menu" id="offcanvas-shop">
  <div class="offcanvas-header">...</div>
  <div class="offcanvas-user">...</div>
  <div class="offcanvas-body">
    <!-- слои меню -->
  </div>
</div>

Оверлей (#overlay-shop) — это пустой div, который изначально невидим (opacity: 0, visibility: hidden). При открытии меню он получает класс .open, который делает его видимым и затемняет экран. Клик по оверлею закрывает соответствующее меню.

Меню (#offcanvas-shop) имеет фиксированное позиционирование слева, изначально сдвинуто за экран (transform: translateX(-100%)). При добавлении класса .open трансформация сбрасывается до translateX(0), и меню плавно выезжает. Структура меню всегда одинакова:

  • offcanvas-header — заголовок с названием и кнопкой закрытия (крестик).
  • offcanvas-user — блок с приветствием и иконкой пользователя.
  • offcanvas-body — основная область, где располагаются уровни меню (главный и подменю).

Для правого меню Account & Lists используется класс .offcanvas-menu-right, который отличается только тем, что прикреплён к правой стороне (right: 0; left: auto;) и изначально сдвинут вправо (transform: translateX(100%)). В остальном логика такая же.

2.4. Система уровней в левых меню

В левых меню (магазин и Help & Settings) применяется многоуровневая структура с анимированными переходами. Это сделано с помощью вложенных div с классом .menu-level, которые позиционированы абсолютно внутри .offcanvas-body. Благодаря этому каждый уровень занимает всё доступное пространство, и при смене уровня один плавно уходит влево, а другой появляется справа.

Вот как это выглядит в разметке магазина:

<div class="offcanvas-body">
  <!-- Главный уровень -->
  <div class="menu-level active" id="mainLevelShop"> ... </div>

  <!-- Подменю Electronics -->
  <div class="menu-level next" id="submenu-electronics"> ... </div>

  <!-- Подменю Computers -->
  <div class="menu-level next" id="submenu-computers"> ... </div>

  <!-- Остальные подменю -->
</div>

Каждый menu-level — это независимый слой. Одновременно видим только один слой, активный (класс active), остальные либо находятся в исходном состоянии (класс next — сдвинуты вправо на 100%), либо скрыты слева (класс hidden-left). Переходы анимируются через CSS transition: transform 0.3s ease.

Главный уровень (#mainLevelShop) содержит категории товаров. Некоторые из них имеют вложенные подменю (например, Electronics). Такие пункты помечены классом .has-submenu и атрибутом data-submenu, значение которого указывает на соответствующий слой (например, data-submenu="electronics"#submenu-electronics).

Подменю (например, #submenu-electronics) начинается с кнопки "назад" (back-button), которая возвращает на главный уровень. Далее идёт список подкатегорий (ссылки с классом .subcategory-item). Подменю также может содержать свои подменю (вложенность не ограничена, хотя в демо используется два уровня).

Точно так же устроено меню Help & Settings: есть главный уровень #mainLevelHelp и несколько подменю (#submenu-help-seasons, #submenu-help-days).

Правое меню Account & Lists не использует уровни, в нём просто прокручиваемый список ссылок. Поэтому его .offcanvas-body имеет overflow-y: auto вместо overflow: hidden; position: relative;.

2.5. Основной контент и футер

После меню идёт <div class="container mt-5"> с заголовком и пустым пространством — это имитация контента. Футер стандартный, содержит четыре колонки с ссылками. Эти части не влияют на работу меню, но показывают, как шаблон выглядит в полном контексте.


3. CSS: превращаем разметку в интерфейс

Теперь перейдём к стилям. Они находятся в файле style.css и отвечают за внешний вид, позиционирование и анимации всех элементов.

3.1. CSS-переменные (custom properties)

В самом начале объявлены переменные в псевдоклассе :root:

:root {
  --amazon-dark: #131921;
  --amazon-light-dark: #232f3e;
  --amazon-yellow: #febd69;
  --amazon-white: #ffffff;
  --menu-width: 365px;
}

Это цвета и базовая ширина меню. Использование переменных упрощает изменение цветовой схемы в будущем: достаточно поменять значения в одном месте. Переменная --menu-width используется для установки ширины offcanvas-контейнеров.

3.2. Стили шапки и навигации

Верхняя строка .top-line имеет тёмный фон, белый текст и flex-раскладку. Flex-wrap позволяет элементам переноситься, если они не помещаются в одну строку (полезно на маленьких экранах). align-items: center выравнивает все элементы по вертикали.

Логотип стилизован: шрифт крупный, полужирный, а буква "A" внутри спана — жёлтая.

Поисковая строка .search-box — flex-контейнер с рамкой. Её flex: 1 заставляет её занимать всё доступное пространство между логотипом и иконками. Внутри select, input и button настроены без границ, с нужными отступами и размерами шрифта.

Иконки пользователя .header-icons — ещё один flex-контейнер, ссылки в котором расположены вертикально (flex-direction: column) для отображения текста в две строки (например, "Hello, sign in" сверху, "Account & Lists" снизу). Иконка корзины немного крупнее, а счётчик позиционирован абсолютно относительно неё.

Нижняя строка .nav-line аналогична верхней, но с другим фоном. Кнопка "All" имеет жёлтый фон, чёрный текст и flex-раскладку для иконки и текста.

Навигационные ссылки .nav-links позволяют горизонтальную прокрутку, если они не помещаются (overflow-x: auto), и обычно отображаются в строку.

3.3. Оверлей и общие стили offcanvas

Оверлей .offcanvas-overlay — фиксированный элемент на весь экран, с полупрозрачным чёрным фоном. По умолчанию он невидим (opacity: 0; visibility: hidden;). При добавлении класса .open оба свойства меняются на 1 и visible, при этом переход transition: opacity 0.2s, visibility 0.2s делает появление плавным.

Для левых меню используется класс .offcanvas-menu. Он также фиксирован, занимает всю высоту экрана, имеет ширину var(--menu-width) (но не более 85vw на случай очень узких экранов). transform: translateX(-100%) сдвигает его за левый край. transition: transform 0.3s ease обеспечивает плавное выдвижение при добавлении класса .open (трансформация становится translateX(0)).

Правое меню .offcanvas-menu-right отличается только положением: left: auto; right: 0; и начальным сдвигом translateX(100%). При открытии оно выезжает справа.

Внутри меню структура:

  • offcanvas-header — тёмный фон, белый текст, flex-строка с названием и кнопкой закрытия.
  • offcanvas-user — чуть светлее, с иконкой пользователя.
  • offcanvas-body — занимает всё оставшееся пространство (flex: 1), имеет position: relative; overflow: hidden;. Это необходимо, так как внутри будут абсолютно позиционированные уровни меню.

3.4. Система уровней меню (для левых меню)

Каждый .menu-level — это position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow-y: auto;. Благодаря этому слой полностью перекрывает родительский .offcanvas-body и может скроллиться, если содержимое не помещается.

По умолчанию слой имеет класс .next, который задаёт transform: translateX(100%) — то есть слой сдвинут вправо и невидим. Когда слой становится активным (.active), его transform: translateX(0), и он выходит на передний план с z-index: 2. Если предыдущий слой уходит влево, он получает класс .hidden-left с transform: translateX(-100%).

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

  • .active — текущий видимый слой.
  • .next — слой, который находится «справа» и ждёт своей очереди.
  • .hidden-left — слой, ушедший влево (например, главный уровень, когда открыто подменю).

Переход между ними анимируется через transition: transform 0.3s ease.

3.5. Элементы внутри меню

Заголовки секций .menu-section-title — серый текст, верхний регистр, небольшой шрифт.

Пункты меню .menu-item — flex-строка, занимающая всю ширину, с отступами, границей снизу. При наведении фон меняется на светло-серый.

Если пункт содержит подменю, он дополнительно имеет класс .has-submenu. Внутри него находится .menu-arrow (стрелка вправо), прижатая к правому краю через margin-left: auto.

Кнопка «назад» .menu-item.back-button имеет более тёмный фон и полужирный шрифт.

Подпункты (в подменю) используют класс .subcategory-item — это блочные элементы со своими отступами.

Разделитель .menu-separator — просто серая линия.

3.6. Стили для правого меню

Правое меню не нуждается в уровнях, поэтому его .offcanvas-body просто прокручивается. Внутри используется список .account-menu-list, стилизованный аналогично пунктам меню, но без абсолютного позиционирования. Кнопка "Sign in" оформлена отдельно.

3.7. Адаптивность

Медиазапрос @media (max-width: 768px) включает несколько изменений:

  • В верхней строке поиск переносится на новую строку (order: 3), что делает его на всю ширину.
  • Появляется кнопка-гамбургер .mobile-nav-toggle (display: block).
  • Навигационные ссылки #navLinks превращаются в выпадающее меню: абсолютное позиционирование под строкой, скрытое по умолчанию (display: none), и показываемое при добавлении класса .show (через JS).
  • Ссылки в выпадающем меню становятся блочными с отступами и разделителями.

Обратите внимание, что ширина offcanvas-меню ограничена max-width: 85vw, чтобы на маленьких экранах оно не выходило за пределы.


4. JavaScript: оживляем меню

Файл script.js содержит всю логику управления тремя offcanvas-меню и мобильной навигацией. Он обёрнут в самовызывающуюся функцию (IIFE), чтобы избежать глобального загрязнения.

4.1. Магазинное меню (кнопка "All")

const allBtn = document.getElementById('allBtn');
const overlayShop = document.getElementById('overlay-shop');
const offcanvasShop = document.getElementById('offcanvas-shop');
const closeShop = document.getElementById('offcanvasCloseShop');
const mainLevelShop = document.getElementById('mainLevelShop');

Здесь мы получаем элементы по их id. Если какой-то элемент не найден, скрипт не ломается, так как мы проверяем наличие кнопки allBtn перед добавлением обработчика (неявно, через факт существования переменной). Но в реальном коде полезно добавить проверки.

Функции открытия и закрытия:

function openShopMenu() {
  overlayShop.classList.add('open');
  offcanvasShop.classList.add('open');
  document.body.style.overflow = 'hidden';
  resetShopMenu();
}
function closeShopMenu() {
  overlayShop.classList.remove('open');
  offcanvasShop.classList.remove('open');
  if (!document.getElementById('offcanvas-help').classList.contains('open') &&
      !document.getElementById('offcanvas-account').classList.contains('open')) {
    document.body.style.overflow = '';
  }
}

Открытие: добавляем класс open оверлею и меню, блокируем прокрутку страницы (body overflow hidden), и сбрасываем уровни меню на главный (функция resetShopMenu).

Закрытие: убираем класс open, но восстанавливаем прокрутку только в том случае, если ни одно другое меню не открыто. Это предотвращает мигание прокрутки при переключении между меню.

Сброс уровней:

function resetShopMenu() {
  mainLevelShop.classList.add('active');
  mainLevelShop.classList.remove('hidden-left');
  offcanvasShop.querySelectorAll('.menu-level').forEach(level => {
    if (level !== mainLevelShop) {
      level.classList.add('next');
      level.classList.remove('active');
    }
  });
}

Эта функция гарантирует, что главный уровень снова станет активным, а все подменю переместятся в состояние «следующее» (сдвинуты вправо). Это нужно при каждом открытии меню, чтобы пользователь всегда начинал с начала.

Обработчики:

  • allBtn.addEventListener('click', ...) — открывает меню магазина.
  • overlayShop.addEventListener('click', closeShopMenu) — закрытие по клику на оверлей.
  • closeShop.addEventListener('click', closeShopMenu) — закрытие по крестику.

Подменю в магазине:

const shopSubmenuTriggers = offcanvasShop.querySelectorAll('.menu-item.has-submenu');
shopSubmenuTriggers.forEach(trigger => {
  trigger.addEventListener('click', function(e) {
    e.stopPropagation();
    const submenuId = this.dataset.submenu;
    const submenu = document.getElementById('submenu-' + submenuId);
    if (!submenu) return;
    mainLevelShop.classList.remove('active');
    mainLevelShop.classList.add('hidden-left');
    submenu.classList.remove('next');
    submenu.classList.add('active');
  });
});

Для каждого пункта с подменю мы вешаем обработчик клика. При клике:

  • Находим соответствующий слой по его id, который формируется как 'submenu-' + значение data-submenu (например, submenu-electronics).
  • Сдвигаем главный уровень влево (класс hidden-left).
  • Убираем у целевого подменю класс next и добавляем active, чтобы он появился.

Кнопки «назад» работают аналогично, но в обратную сторону:

const shopBackButtons = offcanvasShop.querySelectorAll('[data-back]');
shopBackButtons.forEach(btn => {
  btn.addEventListener('click', function(e) {
    e.stopPropagation();
    const parentLevel = this.closest('.menu-level');
    parentLevel.classList.remove('active');
    parentLevel.classList.add('next');
    mainLevelShop.classList.remove('hidden-left');
    mainLevelShop.classList.add('active');
  });
});

Здесь мы находим родительский уровень (текущий подменю), скрываем его (next) и показываем главный уровень.

4.2. Меню Help & Settings

Принцип абсолютно идентичен магазинному, только используются свои элементы и ID. Функции openHelpMenu, closeHelpMenu, resetHelpMenu работают так же. Единственное отличие — формирование ID подменю: 'submenu-help-' + submenuId. Поэтому в разметке эти подменю имеют ID вида submenu-help-seasons.

При открытии Help & Settings мы также закрываем другие меню, если они были открыты, чтобы избежать наложения:

helpLink.addEventListener('click', function(e) {
  e.preventDefault();
  if (offcanvasShop.classList.contains('open')) closeShopMenu();
  if (document.getElementById('offcanvas-account').classList.contains('open')) {
    closeAccountMenu();
  }
  openHelpMenu();
});

4.3. Правое меню Account & Lists

Здесь нет подменю, поэтому логика проще. При открытии просто добавляем класс open, при закрытии убираем. При открытии также закрываем другие меню.

4.4. Закрытие по клавише Escape

document.addEventListener('keydown', function(e) {
  if (e.key === 'Escape') {
    if (offcanvasShop.classList.contains('open')) closeShopMenu();
    if (offcanvasHelp.classList.contains('open')) closeHelpMenu();
    if (offcanvasAccount.classList.contains('open')) closeAccountMenu();
  }
});

Это глобальный обработчик, который закроет любое открытое меню при нажатии Escape.

4.5. Мобильная навигация (гамбургер)

const mobileNavToggle = document.getElementById('mobileNavToggle');
const navLinks = document.getElementById('navLinks');
mobileNavToggle.addEventListener('click', function(e) {
  e.stopPropagation();
  navLinks.classList.toggle('show');
});
document.addEventListener('click', function(e) {
  if (!navLinks.contains(e.target) && e.target !== mobileNavToggle) {
    navLinks.classList.remove('show');
  }
});

Клик по гамбургеру переключает класс show у #navLinks, что делает его видимым (в CSS: #navLinks.show { display: flex; }). Клик в любом месте документа, кроме самого меню и гамбургера, скрывает его. Это стандартный паттерн для выпадающих меню.

4.6. Важные нюансы JavaScript

  • e.stopPropagation() используется, чтобы клик по кнопке или пункту меню не всплывал до document и не вызывал закрытие других меню.
  • Проверка других открытых меню в функциях закрытия гарантирует, что body overflow не восстановится преждевременно.
  • Сброс уровней при каждом открытии исключает ситуацию, когда пользователь видит подменю, оставшееся с прошлого раза.

5. Как это интегрировать в Cotonti CMF или другой движок

Чтобы использовать данный шаблон в своём проекте:

  1. Скопируйте содержимое index.html в файл вашей темы (например, header.tpl в Cotonti). Обычно шапка сайта подключается отдельно.
  2. Подключите style.css в секции <head> вашего шаблона (или добавьте содержимое в основной CSS-файл темы). Убедитесь, что пути к Bootstrap и Font Awesome корректны.
  3. Подключите script.js перед закрывающим </body> с атрибутом defer, чтобы скрипт выполнялся после загрузки DOM. Если ваш движок подключает jQuery, это не помешает — наш скрипт не использует jQuery.
  4. Замените ссылки в меню на реальные URL вашего сайта. Для Cotonti это могут быть теги типа {PHP.cfg.mainurl}, {PHP|cot_url('page', 'm=news')} и т.д.
  5. При необходимости измените цвета и ширину меню в CSS-переменных (:root).

6. Возможные доработки и расширения

  • Добавление анимации аккордеона для мобильных: сейчас подменю всегда работают как сдвиг слоёв. Можно для мобильных изменить поведение, чтобы подкатегории раскрывались внутри пункта (как в оригинале Amazon).
  • Тёмная тема: используя CSS-переменные и атрибут data-theme, можно легко переключать оформление.
  • Улучшение доступности: добавить aria- атрибуты, управление с клавиатуры внутри меню.
  • Интеграция с корзиной: заменить статичный счётчик на динамический через JavaScript.

7. Заключение

Мы детально разобрали, как устроен современный адаптивный шаблон с несколькими независимыми выезжающими меню. Вы узнали, как с помощью HTML создать семантическую структуру, с помощью CSS — стилизовать и анимировать элементы, а с помощью JavaScript — управлять их поведением. Этот код может служить отличной стартовой точкой для создания собственных тем для Cotonti CMF и других CMS.

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

Успешной разработки!



Отзывы

Отзывов пока нет


Комментарии (0)

Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям

Рекомендуемые товары и услуги

Установка, интеграция и адаптация плагинов под Cotonti CMF

Установка, интеграция и адаптация плагинов под Cotonti CMF

профессиональные услуги по установке, глубокой интеграции и адаптации плагинов под Cotonti CMF, с
Index36 - Современная Тема сайта для Cotonti CMF

Index36 - Современная Тема сайта для Cotonti CMF

Index36 не просто шаблон – это полноценная экосистема для управления сайтом. Основной акцент сделан

Обсуждение страницы в Telegram

Автор контента

webitproff

Оффлайн

Carbonate Sodium

Последняя авторизация: 15.07.2026 18:53

  • Чем могу помочь?

    Оказываю весь спектр услуг по CMF Cotonti. Разработка открытых и закрытых корпоративных интернет порталов, небольших социальных сетей, торговые площадки, маркетплейсы, биржи фриланса, каталоги товаров оптовых поставщиков, интернет-магазин под заказ, чтобы делать совместные покупки и групповые совместные продажи от имени нескольких продавцов.

  • Разработки на GitHub бесплатно
    • Страница размещена: 14.07.2026 18:17
    • Последнее обновление: 14.07.2026 18:32
    • Язык:

    Связанные статьи

    Рекомендуемые темы форума для этой статьи

    "Index36" - основной шаблон сайта для Cotonti. Руководство по установке

    "Index36" - основной шаблон сайта для Cotonti. Руководство по установке

    Инструкция по установке темы "Index36" на сайт Cotonti Siena CMF. Удачной установки и красивого
    #188 | Постов: 14 | Просмотров: 1651