使用模块自动构建面包屑
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;
}
}
我的网页有多个模块,我想知道是否有办法将面包屑添加到模块主页 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;
}
}