使用模块自动构建面包屑

Building breadcrumbs automatically with modules

我的网页有多个模块,我想知道是否有办法将面包屑添加到模块主页 url,而无需手动添加到所有文件。 例如:

Home > MyModule > MyController

这个问题确实太宽泛了,但这是我使用的解决方案:

<?php

namespace backend\modules\tests\components;

use yii\helpers\ArrayHelper;
use yii\web\Controller as BaseController;
use yii\web\View;

class Controller extends BaseController
{   
    /**
     * @inheritdoc
     */
    public function beforeAction($action)
    {
        if (parent::beforeAction($action)) {
            Yii::$app->view->on(View::EVENT_BEGIN_BODY, function () {
                $this->fillBreadcrumbs();
            });

            return true;
        } else {
            return false;
        }
    }

    /**
     * Fill common breadcrumbs
     */
    protected function fillBreadcrumbs()
    {
        $breadcrumbs = [];

        // Add needed elements to $breadcrumbs below

        $label = 'Tests';
        $breadcrumbs[] = $this->route == '/tests/default/index' ? $label : [
            'label' => $label,
            'url' => ['/tests/default/index'],
        ];

        // ...

        $this->mergeBreadCrumbs($breadcrumbs);
    }

    /**
     * Prepend common breadcrumbs to existing ones
     * @param array $breadcrumbs
     */
    protected function mergeBreadcrumbs($breadcrumbs)
    {
        $existingBreadcrumbs = ArrayHelper::getValue($this->view->params, 'breadcrumbs', []);
        $this->view->params['breadcrumbs'] = array_merge($breadcrumbs, $existingBreadcrumbs);
    }
}

如您所见,它基于视图事件和自定义控制器(从 yii\web\Controller 扩展而来)。

接下来您需要做的就是从自定义控制器扩展所需的控制器。

Pjax 用户注意事项

如果您在索引视图等上使用 Pjax,请确保按如下方式添加 'data-pjax'=>'0' 选项,否则请求将刷新现有视图中的新上下文:

Html::a('AnotherView',
    ['another-view', 'id' => $model->$id], [
    'data-pjax' => '0', // !important when using pjax.
]);

app/config/main.php

'modules' => [
    /*
     *  Admin => [...], // in common for frontend/backend access.
     */
    'estimator' => [
        'class' => 'your\namespace\Module',
        'defaultUrl' => '/estimator/',
        'defaultUrlLabel' => 'Estimator',
        //'layout' => 'left-menu',
        //'mainLayout' => '@app/views/layouts/main.php',
    ],
],

your-app/Module.php

<?php
namespace yourapp\namespace;

use Yii;
use yii\helpers\Inflector;
use yii\helpers\ArrayHelper;
/**
 * Entry for module...
  */
class Module extends \yii\base\Module
{
    /**
     * @var string Layout applied for views in module.
     * Comment out $layout to use default parent layout.
     * When $layout is enabled, the mainLayout will be utilized instead of the default layout for the site.
     */
    //public $layout = "top-menu.php"; // comment out to disable module layout.

    /**
     * @var string Main layout using for module. Default to layout of parent module.
     * The mainLayout is used when `layout` set to 'top-menu'.
     */
    //public $mainLayout = '@frontend/views/layouts/main.php';

    /**
     * @inheritdoc
     */
    public $defaultRoute = 'project';

    /**
     * @var string Default url for breadcrumb
     */
    public $defaultUrl;

    /**
     * @var string Default url label for breadcrumb
     */
    public $defaultUrlLabel;

    /**
     * @inheritdoc
     */
    public function beforeAction($action)
    {
        if (parent::beforeAction($action)) {
            /* @var $action \yii\base\Action */
            $view = $action->controller->getView();
            $view->params['breadcrumbs'][] = [
                'label' => ($this->defaultUrlLabel ?: 'Warehouse'),
                'url' => ['/' . ($this->defaultUrl ?: $this->uniqueId)],
            ];
            $view->params['breadcrumbs'][] = [
                'label' => Inflector::pluralize(Inflector::camelize($action->controller->id)),
                'url' => ['/' . ($this->defaultUrl ?: $this->uniqueId) . '/' . $action->controller->id],
            ];
            $view->params['breadcrumbs'][] = [
                'label' => Inflector::camelize($action->id),
            ];
            return true;
        }
        return false;
    }
}