首页 > 解决方案 > 用一种形式自定义整个 symfony 网站的 UI

问题描述

我试图让某种类型的用户自定义 symfony 网站的 UI。我有点迷失在提交表单时如何覆盖css属性。此外,数据将保存在 AWS S3 云中。所以我需要为此创建一个连接器服务。

我为此功能创建了控制器、实体、存储库和模板。

这是控制器:

<?php

namespace App\Controller;

use App\Entity\OrganizationCustomization;
use App\Forms\CustomizationFormType;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class OrganizationCustomizationController extends AbstractController
{
    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @Route("/organization/customization", name="organization_customization")
     *
     * @param Request $request
     *
     * @return Response
     */
    public function buildForm(
        Request $request
    ) {
        //If user do not have permission we redirect him to the dashboard
        if (!$this->isGranted('ROLE_COMPANY_MANAGER', '') || !$this->isGranted('ROLE_SUPERADMIN', '')) {
            $this->redirectToRoute('dashboard');
        }
        //Calling the organization customization form
        $organizationCustomization = new OrganizationCustomization();
        $form = $this->createForm(CustomizationFormType::class, $organizationCustomization);

        //Get companyId of the user to set it in OrganizationCustomization entity
        $companyId = $this->getUser()->getCompany()->getId();

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $organizationCustomization = $form->getData();
            $organizationCustomization->setId($companyId);
            $organizationCustomization->setIsActive(true);

            /** @var UploadedFile $logoFile */
            $logoFile = $form['logoFile']->getData();

            if ($logoFile) {
                $originalFilename = pathinfo($logoFile->getClientOriginalName(), PATHINFO_FILENAME);
                // this is needed to safely include the file name as part of the URL
                $safeFilename = transliterator_transliterate(
                    'Any-Latin; Latin-ASCII; [^A-Za-z0-9_] remove; Lower()',
                    $originalFilename
                );
                $newFilename = $safeFilename.'-'.uniqid().'.'.$logoFile->guessExtension();
                // Move the file to the directory where images are stored
                try {
                    $logoFile->move(
                        $this->getParameter('company_logo_directory'),
                        $newFilename
                    );
                } catch (FileException $e) {
                    // handle exception if something happens during file upload

                    $this->logger->info('File upload has failed '.$e);
                }
                // updates the 'logoFilename' property to store the PDF file name
                // instead of its contents
                $organizationCustomization->setLogoFile($newFilename);
                dump($organizationCustomization);
            }
        }

        return $this->render('organization_customization/index.html.twig', [
            'form' => $form->createView(),
        ]);
    }
}

这是实体:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\OrganizationCustomizationRepository")
 */
class OrganizationCustomization
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=7, nullable=true)
     */
    private $backgroundColor;

    /**
     * @ORM\Column(type="string", length=7, nullable=true)
     */
    private $fontColor;

    /**
     * @ORM\Column(type="string", length=7, nullable=true)
     */
    private $baseSiteColor;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $logoFile;

    /**
     * @ORM\Column(type="boolean")
     */
    private $isActive;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function setId(?int $id): self
    {
        $this->id = $id;

        return $this;
    }

    public function getBackgroundColor(): ?string
    {
        return $this->backgroundColor;
    }

    public function setBackgroundColor(?string $backgroundColor): self
    {
        if (true === \mb_strpos($backgroundColor, '#')) {
            $this->backgroundColor = $backgroundColor;
        }

        return $this;
    }

    public function getFontColor(): ?string
    {
        return $this->fontColor;
    }

    public function setFontColor(?string $fontColor): self
    {
        if (true === \mb_strpos($fontColor, '#')) {
            $this->fontColor = $fontColor;
        }

        return $this;
    }

    public function getBaseSiteColor(): ?string
    {
        return $this->baseSiteColor;
    }

    public function setBaseSiteColor(?string $baseSiteColor): self
    {
        if (true === \mb_strpos($baseSiteColor, '#')) {
            $this->baseSiteColor = $baseSiteColor;
        }

        return $this;
    }

    public function getLogoFile(): ?string
    {
        return $this->logoFile;
    }

    public function setLogoFile(?string $logoFile): self
    {
        $this->logoFile = $logoFile;

        return $this;
    }

    public function getIsActive(): ?bool
    {
        return $this->isActive;
    }

    public function setIsActive(bool $isActive): self
    {
        $this->isActive = $isActive;

        return $this;
    }
}

这是我的模板:

{% block headtop %}
    <title>{% block title %}Harmonie Technologie{% endblock %}</title>
    {% include "head.html.twig" %}
{% endblock headtop %}
{% include "css.html.twig" %}

<body>
    {% block body %}

        {#{{ form(form.backgroundColor, {attr: {class: 'customize-background-color'}}) }}
        {{ form(form.fontColor) }}
        {{ form(form.baseSiteColor) }}
        {{ form(form.logoFile) }}#}
        {{ form(form) }}

{% endblock %}
</body>

现在,当我提交表单时,我得到了正确的值,但我试图覆盖仅包含以下内容的 templates/css.html.twig:

<link href="{{absolute_url("/bootstrap/css/bootstrap.min.css")}}" rel="stylesheet"/>
<link href="{{absolute_url("/fontawesome-5.6.3/css/all.min.css")}}" rel="stylesheet">
<link href="{{absolute_url("/jquery-ui-1.12.1.custom/jquery-ui.min.css")}}" rel="stylesheet">
<link href="{{absolute_url("/jquery-ui-1.12.1.custom/jquery-ui.structure.min.css")}}" rel="stylesheet">
<link href="{{absolute_url("/css/riskandme.css")}}" rel="stylesheet">
<link href="{{absolute_url('/css/bootstrap-datetimepicker.css')}}" rel="stylesheet"/>

非常感谢您的关注和帮助。

标签: javascriptcsssymfonytwig

解决方案


如果要保留用户首选项,则需要将其保存在数据库中。有一些可能性。

@Wouter J 使用了那个:

1)创建一个样式表,例如 styles.css.twig 并将内容放在那里。例如:

.user-color{
    color: {{ user_color }};
}

现在,创建一个渲染此文件并将其保存在某处的类:

class TemplateRenderer
{
    protected $basepath;
    protected $templating;
    protected $parameters = array();

    public function __construct($templating, $basepath, $styleseheetpath)
    {
        $this->basepath = $basepath; /* "%kerel.base_path" parameter */
        $this->templating = $templating; /* "twig" service */
        $this->stylesheetpath = $stylesheetpath; /* custom defined parameter */
    }

    public function setParam($id, $value)
    {
        $this->parameters[$id] = $value;
    }

    public function render()
    {
        file_put_contents(
            $this->basepath.'/web/assets/css/styles.css',
            $this->templating->render(
                $this->stylesheetpath,
                $this->parameters
            )
        );
    }
}

将此类注册为服务并将其注册为事件后监听器(http://symfony.com/doc/current/cookbook/event_dispatcher/before_after_filters.html)。

从您的控制器(或使用方法注入的事件配置文件),您可以调用 setParam 方法来设置变量。

在您的基本 html 文件中,您可以使用它的路径(现在,web/assets/css/styles.css)包含此文件。

请注意,代码是一个示例。肯定需要一些错误处理和缓存才能使其在生产中可用。

来源:Symfony2:在样式表中使用 Twig 变量

2)您可以使用树枝“包含”:

 {% include 'style.css' with {'color': user.color} %}

来源:https ://twig.symfony.com/doc/2.x/tags/include.html

3)您可以使用不同的预格式化 css 文件:

例如,您可以在数据库中有一个字段“ui_color”。用户可以提交表单并选择“绿色”或“橙色”。

你有两个css文件,一个是“green-theme.css”,另一个是“orange-theme.css”。

然后你在你的树枝文件中调用它,如:

{% include myUser.ui_color ~ ".css" %}

4) 你可以在你的 twig 文件中使用内联 css,并使用 twig 变量来修改其中的一些值。


推荐阅读