Разработка сайта на CMS Sulu

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

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка сайта на CMS Sulu
Сложная
~2-4 недели
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка сайта на CMS Sulu

Sulu — enterprise CMS на Symfony. Headless из коробки, REST и JSON:API, мультисайт, мультиязычность, Webspaces. Построен на Doctrine ORM, работает с MySQL/MariaDB/PostgreSQL. Целевая аудитория — корпоративные сайты, порталы, мультибрендовые платформы.

Архитектура

my-sulu-project/
├── assets/              # фронтенд ресурсы (webpack/vite)
├── bin/
├── config/
│   ├── packages/
│   │   ├── sulu.yaml    # конфиг Sulu
│   │   └── webspaces/
│   │       └── example.xml
│   ├── routes_admin.yaml
│   ├── routes_website.yaml
│   └── services.yaml
├── src/
│   ├── Controller/
│   │   ├── Admin/       # кастомные API для backoffice
│   │   └── Website/     # публичные контроллеры
│   ├── Entity/          # Doctrine-сущности
│   ├── EventSubscriber/
│   └── Twig/
├── templates/           # Twig-шаблоны
│   ├── base.html.twig
│   └── pages/
│       ├── homepage.html.twig
│       └── article.html.twig
└── public/

Конфигурация Webspace

<!-- config/packages/webspaces/example.xml -->
<?xml version="1.0" encoding="utf-8"?>
<webspace xmlns="http://schemas.sulu.io/webspace/webspace"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://schemas.sulu.io/webspace/webspace
          http://schemas.sulu.io/webspace/webspace-1.1.xsd">

    <name>Example</name>
    <key>example</key>

    <localizations>
        <localization language="ru" default="true"/>
        <localization language="en"/>
    </localizations>

    <default-templates>
        <default-template type="page">homepage</default-template>
        <default-template type="home">homepage</default-template>
    </default-templates>

    <templates>
        <template type="page">homepage</template>
        <template type="page">article</template>
        <template type="page">article-list</template>
        <template type="page">contact</template>
    </templates>

    <portals>
        <portal>
            <name>Example</name>
            <key>example</key>
            <environments>
                <environment type="prod">
                    <urls>
                        <url language="ru">example.com</url>
                        <url language="en">en.example.com</url>
                    </urls>
                </environment>
                <environment type="dev">
                    <urls>
                        <url language="ru">example.localhost</url>
                    </urls>
                </environment>
            </environments>
        </portal>
    </portals>
</webspace>

Page Template

<!-- config/templates/article.xml -->
<?xml version="1.0" encoding="utf-8"?>
<template xmlns="http://schemas.sulu.io/template/template"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://schemas.sulu.io/template/template
          http://schemas.sulu.io/template/template-1.0.xsd">

    <key>article</key>
    <view>pages/article</view>
    <controller>Sulu\Bundle\WebsiteBundle\Controller\DefaultController::indexAction</controller>
    <cacheLifetime>3600</cacheLifetime>

    <properties>
        <property name="title" type="text_line" mandatory="true">
            <meta>
                <title lang="ru">Заголовок</title>
            </meta>
            <tag name="sulu.rlp.part"/>
        </property>

        <property name="article" type="text_editor" colspan="12">
            <meta>
                <title lang="ru">Текст статьи</title>
            </meta>
        </property>

        <property name="header_image" type="single_media_selection" colspan="12">
            <meta>
                <title lang="ru">Изображение</title>
            </meta>
            <params>
                <param name="types" value="image"/>
            </params>
        </property>

        <section name="seo">
            <meta>
                <title lang="ru">SEO</title>
            </meta>
            <properties>
                <property name="seo_title" type="text_line" colspan="6">
                    <meta><title lang="ru">SEO заголовок</title></meta>
                </property>
                <property name="seo_description" type="text_area" colspan="6">
                    <meta><title lang="ru">SEO описание</title></meta>
                </property>
            </properties>
        </section>
    </properties>
</template>

Twig-шаблон

{# templates/pages/article.html.twig #}
{% extends 'base.html.twig' %}

{% block title %}{{ content.seo_title ?: content.title }} | {{ app.request.host }}{% endblock %}

{% block body %}
<article class="page-article">
    <header class="article-header">
        {% if content.header_image %}
            {% set image = sulu_resolve_media(content.header_image, 'ru') %}
            <figure>
                <img
                    src="{{ image.thumbnails['800x450'] }}"
                    srcset="{{ image.thumbnails['400x225'] }} 400w,
                            {{ image.thumbnails['800x450'] }} 800w"
                    alt="{{ image.title }}"
                >
            </figure>
        {% endif %}
        <h1>{{ content.title }}</h1>
    </header>

    <div class="article-body">
        {{ content.article|raw }}
    </div>
</article>
{% endblock %}

Кастомный контроллер

// src/Controller/Website/ArticleListController.php
namespace App\Controller\Website;

use Sulu\Bundle\WebsiteBundle\Resolver\TemplateAttributeResolverInterface;
use Sulu\Component\Content\Compat\StructureInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class ArticleListController extends AbstractController
{
    public function __construct(
        private readonly TemplateAttributeResolverInterface $resolver,
        private readonly ArticleRepository $repository
    ) {}

    public function indexAction(StructureInterface $structure, bool $preview = false): Response
    {
        $page = max(1, (int) $this->container->get('request_stack')
            ->getCurrentRequest()
            ->query->get('page', 1));

        $articles = $this->repository->findPublished(page: $page, limit: 12);

        $attributes = $this->resolver->resolve([
            'content'  => $structure->getContent(),
            'articles' => $articles,
            'pagination' => [
                'current' => $page,
                'total'   => $articles->getTotalPages(),
            ],
        ], $structure, true, $preview);

        return $this->render('pages/article-list.html.twig', $attributes);
    }
}

Sulu Media и ресайз

{% set media = sulu_resolve_media(content.image, locale) %}

{# предопределённый формат #}
<img src="{{ media.thumbnails['sulu-400x400'] }}" alt="{{ media.title }}">

{# произвольный ресайз через URL-параметры #}
<img src="{{ media.url }}?w=800&h=600&fm=webp&q=85" alt="">

Форматы конфигурируются в config/packages/sulu.yaml:

sulu_media:
    image_format_files:
        - '%kernel.project_dir%/config/image-formats.xml'
<!-- config/image-formats.xml -->
<formats>
    <format key="article-cover">
        <commands>
            <command>
                <action>resize</action>
                <parameters>
                    <parameter name="x">800</parameter>
                    <parameter name="y">450</parameter>
                </parameters>
            </command>
        </commands>
    </format>
</formats>

Smart Content и автосписки

<property name="articles" type="smart_content">
    <meta><title lang="ru">Статьи</title></meta>
    <params>
        <param name="provider" value="pages"/>
        <param name="types" value="article"/>
        <param name="max_per_page" value="6"/>
        <param name="page_parameter" value="p"/>
    </params>
</property>

В шаблоне:

{% for article in content.articles %}
    {% include 'snippets/article-card.html.twig' with { page: article } %}
{% endfor %}

Сроки

Корпоративный сайт с двумя языками, 5–8 типами страниц, медиа-менеджером и кастомными шаблонами: 4–6 недель. С кастомными контроллерами, Smart Content, интеграцией с внешними сервисами: 6–10 недель.