【问题标题】:How can I add simple CMS functionality to existing Symfony application如何向现有 Symfony 应用程序添加简单的 CMS 功能
【发布时间】:2017-04-17 01:21:38
【问题描述】:

我有一个访问 MySQL 数据库的现有 Web 应用程序。我正在将此应用程序移植到 Symfony。新应用程序必须使用旧数据库,因为我们不能一次移植整个应用程序,即旧应用程序和新应用程序正在访问同一个数据库并且应用程序同时运行。

旧应用程序有一个简单的 CMS 功能,需要移植:

有一个表page代表一个页树。每个页面都有一个slug 字段。 URL 路径由代表标识页面节点的路径的那些 slug 组成,例如"/[parent-slug]/[child-slug]".

页表还包含一个content 字段。正如我已经提到的,CMS 功能非常简单,因此内容只是呈现为页面布局内的页面内容。页面条目还指定页面布局/模板。

我的问题是我不知道如何设置路由。在一个普通的 Symfony 应用程序中,我以前知道 URL 模式,但在这种情况下它们是动态的。路由也不能被缓存,因为用户可以随时更改它们。我想知道我是否必须完全放弃 Symfony 的路由并自己实现一些东西。但是怎么做呢?

现在我找到了 Symfony CMF,它讲述了很多关于框架 VS CMS 路由冲突的信息。所以首先,我认为这是正确的方法。然而,这些教程旨在构建一个基于 PHPRC 的全新应用程序。我无法将教程的概念推导出到我的用例中。

【问题讨论】:

  • 我编辑并澄清了这个问题。希望要么反对票被删除,要么反对票的人解释一下,这里有什么问题

标签: content-management-system symfony symfony-cmf symfony-routing


【解决方案1】:

因为您在一个 symfony 应用程序上运行了多个 URL 规则,所以您需要使用 url 前缀。您的 cms 应该使用前缀 /cms/parent-slug/child-slug 或所有其他控制器。否则,当动态请求到达时,您无法区分哪个控制器是指哪个控制器。

您可以尝试使用 KernelControllerListener 的解决方法。他将赶上每个请求,然后检查是否请求了 cms 页面。您可以根据请求自行设置控制器和操作。概念:

只用“/”创建一个路由。放弃其他规则。然后像这样创建一个监听器:

<?php

namespace AppBundle\Listener;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

/**
 * Class KernelControllerListener
 * @package ApiBundle\Listener
 */
class KernelControllerListener
{
    /**
     * @var CmsRepository
     */
    private $requestParser;

    /**
     * KernelControllerListener constructor.
     * @param CmsRepository $CmsRepository
     */
    public function __construct(CmsRepository $CmsRepository)
    {
        $this->CmsRepository = $CmsRepository;
    }

    /**
     * @param FilterControllerEvent $event
     */
    public function onKernelController(FilterControllerEvent $event){
        $request = $event->getRequest();
        //should be /parent-slug/children/slug or any other path
        $path = $request->getPathInfo();

        if($this->CmsRepository->getCmsControllerIfMatch($path)){
            //cms repository search in db for page with this path, otherwise return false
            $event->setController([AppBundle\CmsController::class, 'cmsAction']);
            return;
        }

        //repeat if clause for any other application part
    }
}

在 services.yml 中:

app.controller_listener:
  class: AppBundle\Listener\KernelControllerListener
  arguments:
    - "@app.cms_repository"
  tags:
    - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

编辑:捕获所有路线,见https://www.jverdeyen.be/symfony2/symfony-catch-all-route/

【讨论】:

    【解决方案2】:

    问题是:您是否要迁移数据。对于这两个问题,CMF 都可以作为答案。如果您想要一个简单的动态路由器,您应该查看带有自定义路由器定义的ChainRouterhttps://symfony.com/doc/current/cmf/bundles/routing/dynamic.htmlhttps://symfony.com/doc/current/cmf/components/routing/chain.html 如果您想迁移数据,您可以使用夹具加载器,我们在几乎所有示例中都使用。

    【讨论】:

      猜你喜欢
      • 2015-11-04
      • 2016-05-10
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      相关资源
      最近更新 更多