Breadcrumbs.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\widgets;
  8. use Yii;
  9. use yii\base\Widget;
  10. use yii\base\InvalidConfigException;
  11. use yii\helpers\Html;
  12. /**
  13. * Breadcrumbs displays a list of links indicating the position of the current page in the whole site hierarchy.
  14. *
  15. * For example, breadcrumbs like "Home / Sample Post / Edit" means the user is viewing an edit page
  16. * for the "Sample Post". He can click on "Sample Post" to view that page, or he can click on "Home"
  17. * to return to the homepage.
  18. *
  19. * To use Breadcrumbs, you need to configure its [[links]] property, which specifies the links to be displayed. For example,
  20. *
  21. * ~~~
  22. * // $this is the view object currently being used
  23. * echo Breadcrumbs::widget([
  24. * 'links' => [
  25. * ['label' => 'Sample Post', 'url' => ['post/edit', 'id' => 1]],
  26. * 'Edit',
  27. * ],
  28. * ]);
  29. * ~~~
  30. *
  31. * Because breadcrumbs usually appears in nearly every page of a website, you may consider placing it in a layout view.
  32. * You can use a view parameter (e.g. `$this->params['breadcrumbs']`) to configure the links in different
  33. * views. In the layout view, you assign this view parameter to the [[links]] property like the following:
  34. *
  35. * ~~~
  36. * // $this is the view object currently being used
  37. * echo Breadcrumbs::widget([
  38. * 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
  39. * ]);
  40. * ~~~
  41. *
  42. * @author Qiang Xue <[email protected]>
  43. * @since 2.0
  44. */
  45. class Breadcrumbs extends Widget
  46. {
  47. /**
  48. * @var string the name of the breadcrumb container tag.
  49. */
  50. public $tag = 'ul';
  51. /**
  52. * @var array the HTML attributes for the breadcrumb container tag.
  53. */
  54. public $options = ['class' => 'breadcrumb'];
  55. /**
  56. * @var boolean whether to HTML-encode the link labels.
  57. */
  58. public $encodeLabels = true;
  59. /**
  60. * @var string the first hyperlink in the breadcrumbs (called home link).
  61. * If this property is not set, it will default to a link pointing to [[\yii\web\Application::homeUrl]]
  62. * with the label 'Home'. If this property is false, the home link will not be rendered.
  63. */
  64. public $homeLink;
  65. /**
  66. * @var array list of links to appear in the breadcrumbs. If this property is empty,
  67. * the widget will not render anything. Each array element represents a single link in the breadcrumbs
  68. * with the following structure:
  69. *
  70. * ~~~
  71. * [
  72. * 'label' => 'label of the link', // required
  73. * 'url' => 'url of the link', // optional, will be processed by Html::url()
  74. * ]
  75. * ~~~
  76. *
  77. * If a link is active, you only need to specify its "label", and instead of writing `['label' => $label]`,
  78. * you should simply use `$label`.
  79. */
  80. public $links = [];
  81. /**
  82. * @var string the template used to render each inactive item in the breadcrumbs. The token `{link}`
  83. * will be replaced with the actual HTML link for each inactive item.
  84. */
  85. public $itemTemplate = "<li>{link}</li>\n";
  86. /**
  87. * @var string the template used to render each active item in the breadcrumbs. The token `{link}`
  88. * will be replaced with the actual HTML link for each active item.
  89. */
  90. public $activeItemTemplate = "<li class=\"active\">{link}</li>\n";
  91. /**
  92. * Renders the widget.
  93. */
  94. public function run()
  95. {
  96. if (empty($this->links)) {
  97. return;
  98. }
  99. $links = [];
  100. if ($this->homeLink === null) {
  101. $links[] = $this->renderItem([
  102. 'label' => Yii::t('yii', 'Home'),
  103. 'url' => Yii::$app->homeUrl,
  104. ], $this->itemTemplate);
  105. } elseif ($this->homeLink !== false) {
  106. $links[] = $this->renderItem($this->homeLink, $this->itemTemplate);
  107. }
  108. foreach ($this->links as $link) {
  109. if (!is_array($link)) {
  110. $link = ['label' => $link];
  111. }
  112. $links[] = $this->renderItem($link, isset($link['url']) ? $this->itemTemplate : $this->activeItemTemplate);
  113. }
  114. echo Html::tag($this->tag, implode('', $links), $this->options);
  115. }
  116. /**
  117. * Renders a single breadcrumb item.
  118. * @param array $link the link to be rendered. It must contain the "label" element. The "url" element is optional.
  119. * @param string $template the template to be used to rendered the link. The token "{link}" will be replaced by the link.
  120. * @return string the rendering result
  121. * @throws InvalidConfigException if `$link` does not have "label" element.
  122. */
  123. protected function renderItem($link, $template)
  124. {
  125. if (isset($link['label'])) {
  126. $label = $this->encodeLabels ? Html::encode($link['label']) : $link['label'];
  127. } else {
  128. throw new InvalidConfigException('The "label" element is required for each link.');
  129. }
  130. if (isset($link['url'])) {
  131. return strtr($template, ['{link}' => Html::a($label, $link['url'])]);
  132. } else {
  133. return strtr($template, ['{link}' => $label]);
  134. }
  135. }
  136. }