基于模块化CMS的动态菜单模块的最佳实践

时间:2016-08-03 19:03:53

标签: php laravel laravel-5.2

好吧,我知道标题可能有点奇怪。但我不知道怎么说。基本上它归结为一些简单的东西,但有时作为一个开发人员会让你提出问题并让你想与其他开发人员讨论它。

快速介绍问题:我将基于流行的PHP框架重新开发我的CMS(Fyi:Laravel是我的选择)。 CMS将是模块化的(博客,用户,页面,表格等),但我也希望网站所有者可以管理网站导航。这是我开始考虑这样做的最佳实践。

到目前为止,我在想的是创建一个界面“MenuBuilder”,它定义了为给定模块生成菜单链接时需要知道的方法。所以,假设我的BlogModule有一个类BlogMenuBuilder。

MenuBuilder类将有一个基于none或一些参数(如记录ID)构建链接的方法,生成所有链接的方法,为下拉列表生成选项数组的方法等。< / p>

然后MenuModule将类名和可选参数保存到表中,连同菜单位置(顶部,页脚,侧边栏等),我可以调用MenuModule::build('top'),此函数将找到所有链接,排序的话题,并通过调用BlogMenuBuilder::link('type', $optional_parameters);来构建链接。在这种情况下,类型将是Laravel框架中的命名路由。最终,MenuModule :: build()方法将缓存,而不是每次都必须再次构建它。

我是否接近最佳做法?我觉得我正朝着正确的方向前进,但由于我没有其他开发人员认为这件事我希望从SO获得一些可用的反馈。

谢谢你的时间!

2 个答案:

答案 0 :(得分:5)

我认为你在结构方面几乎就是这样。基于我对你的问题的理解(以及你正在使用Laravel),我会这样做:

数据库

Name:    menus
Columns: id | builder | created_at          | updated_at          | deleted_at
         ---------------------------------------------------------------------
     eg. 1  | NULL    | 1985-10-26 01:20:00 | 1985-10-26 01:21:00 | NULL
         2  | blog    | 1985-10-26 01:20:00 | 1985-10-26 01:21:00 | NULL


Name:    links
Columns: id | menu_id | type  | resource_type | resource_id | url                       | created_at          | updated_at          | deleted_at
         -------------------------------------------------------------------------------------------------------------------------------
     eg. 1  | 1       | url   | NULL          | NULL        | http://example.com/blog/1 | 1985-10-26 01:20:00 | 1985-10-26 01:21:00 | NULL
         1  | 2       | route | blog          | 1           | NULL                      | 1985-10-26 01:20:00 | 1985-10-26 01:21:00 | NULL


Name:    meta (or options)
Columns: id | resource_type | resource_id | name     | value
         ---------------------------------------------------
     eg. 1  | menu          | 1           | bg_color | 000000
         2  | link          | 1           | target   | _blank

使用此表设置,您可以存储菜单,链接(在相关构建器或URL中定义的路径)和菜单或链接的元/选项数据。

注意:如果您想重新使用多个菜单中的链接,可以从menu_id表格中删除links,为表格添加menu_links表格菜单和链接之间的ManyToMany relationship

模型

很简单,你想要每个表的模型,即。 MenuLinkMeta

助洗剂

在项目的app目录中,我会在其中放置一个Builders文件夹和一个MenuBuilders文件夹。使用该结构,您可以在Builder下为每个App\Builders\MenuBuilders类命名。

对于每个Builder课程,您可以扩展主MenuBuilder课程,或者根据每个Builder的更改量,您可以implement { {1}}。这是一个使用interface的快速示例(如果您不熟悉接口,我建议您查看Laracasts PHP Bootcamp):

<强> MenuBuilderInterface.php

interface

<强> BlogMenuBuilder.php

namespace App\Builders\MenuBuilders;

interface MenuBuilderInterface{
    /* 
     * Build function
     *
     * @param object $menu
     */
    public build($menu);
}

如果您不想创建namespace App\Builders\MenuBuilders; class BlogMenuBuilder implements MenuBuilderInterface { /* * Build function * * @param object $menu */ public build($menu) { // Here you can now build your menu using // the menu instance passed through } } 中签约的所有方法,那么扩展主interface类对您来说效果更好,这实际上取决于您看到菜单的不同之处是否以及是否可以在主MenuBuilder中重复使用大量方法。

实践

那么你将如何使用上述设置?就像你在问题中所述,每个MenuBuilder在数据库中定义它的构建器,因此我们可以在menu模型中创建一个简单的构建函数来调用正确的Menu类:

<强> Menu.php

Builder

现在我们在视图中需要做的就是在菜单实例上调用构建函数:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Menu extends Model
{
    /**
     * Get the user's first name.
     *
     * @param  string  $value
     * @return string
     */
    public function build()
    {
        // First we define our namespace and get the builder based on the menu data
        $namespace = 'App\\Builders\\MenuBuilders\\';
        $builder   = !empty($this->builder)? $namespace.ucfirst($this->builder).'MenuBuilder' : $namespace.'MenuBuilder';

        // Then check the builder class defined definitely exists
        // If no, replace with main menu builder class
        $builder = class_exists($builder)? $builder : $namespace.'MenuBuilder';

        // Lastly we call the build method on a new instance of our builder
        // passing in our menu instance
        return new $builder()->build($this);
    }
}

总有一些不同的方法可以构建这种东西。根据你所追求的每个结果的具体要求,你不可避免地会找出最适合你的东西,但我希望有所帮助!

答案 1 :(得分:2)

正如大家所说的那样,做其他大cms'做过的事。

所以在UI上: - 有一个现有菜单选择框 - 有一个按钮来创建一个新菜单

  • 创建或添加菜单时
  • 您将有一个添加新项目的按钮
  • 点击新项目时,您会看到一个包含所有页面的框 - &gt;

这部分可能比您的网站更复杂: - 包含静态页面:/,/ about,/ contact - 包含动态页面(就像wordpress一样) - 包含动态帖子(就像wordpress一样) - 包含动态类别,标记任何内容(就像wordpress) - 免费输入框