Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

182 lines
6.6KB

  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\ArrayHelper;
  12. use yii\helpers\Html;
  13. /**
  14. * Breadcrumbs displays a list of links indicating the position of the current page in the whole site hierarchy.
  15. *
  16. * For example, breadcrumbs like "Home / Sample Post / Edit" means the user is viewing an edit page
  17. * for the "Sample Post". He can click on "Sample Post" to view that page, or he can click on "Home"
  18. * to return to the homepage.
  19. *
  20. * To use Breadcrumbs, you need to configure its [[links]] property, which specifies the links to be displayed. For example,
  21. *
  22. * ```php
  23. * // $this is the view object currently being used
  24. * echo Breadcrumbs::widget([
  25. * 'itemTemplate' => "<li><i>{link}</i></li>\n", // template for all links
  26. * 'links' => [
  27. * [
  28. * 'label' => 'Post Category',
  29. * 'url' => ['post-category/view', 'id' => 10],
  30. * 'template' => "<li><b>{link}</b></li>\n", // template for this link only
  31. * ],
  32. * ['label' => 'Sample Post', 'url' => ['post/edit', 'id' => 1]],
  33. * 'Edit',
  34. * ],
  35. * ]);
  36. * ```
  37. *
  38. * Because breadcrumbs usually appears in nearly every page of a website, you may consider placing it in a layout view.
  39. * You can use a view parameter (e.g. `$this->params['breadcrumbs']`) to configure the links in different
  40. * views. In the layout view, you assign this view parameter to the [[links]] property like the following:
  41. *
  42. * ```php
  43. * // $this is the view object currently being used
  44. * echo Breadcrumbs::widget([
  45. * 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
  46. * ]);
  47. * ```
  48. *
  49. * @author Qiang Xue <qiang.xue@gmail.com>
  50. * @since 2.0
  51. */
  52. class Breadcrumbs extends Widget
  53. {
  54. /**
  55. * @var string the name of the breadcrumb container tag.
  56. */
  57. public $tag = 'ul';
  58. /**
  59. * @var array the HTML attributes for the breadcrumb container tag.
  60. * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
  61. */
  62. public $options = ['class' => 'breadcrumb'];
  63. /**
  64. * @var boolean whether to HTML-encode the link labels.
  65. */
  66. public $encodeLabels = true;
  67. /**
  68. * @var array the first hyperlink in the breadcrumbs (called home link).
  69. * Please refer to [[links]] on the format of the link.
  70. * If this property is not set, it will default to a link pointing to [[\yii\web\Application::homeUrl]]
  71. * with the label 'Home'. If this property is false, the home link will not be rendered.
  72. */
  73. public $homeLink;
  74. /**
  75. * @var array list of links to appear in the breadcrumbs. If this property is empty,
  76. * the widget will not render anything. Each array element represents a single link in the breadcrumbs
  77. * with the following structure:
  78. *
  79. * ```php
  80. * [
  81. * 'label' => 'label of the link', // required
  82. * 'url' => 'url of the link', // optional, will be processed by Url::to()
  83. * 'template' => 'own template of the item', // optional, if not set $this->itemTemplate will be used
  84. * ]
  85. * ```
  86. *
  87. * If a link is active, you only need to specify its "label", and instead of writing `['label' => $label]`,
  88. * you may simply use `$label`.
  89. *
  90. * Since version 2.0.1, any additional array elements for each link will be treated as the HTML attributes
  91. * for the hyperlink tag. For example, the following link specification will generate a hyperlink
  92. * with CSS class `external`:
  93. *
  94. * ```php
  95. * [
  96. * 'label' => 'demo',
  97. * 'url' => 'http://example.com',
  98. * 'class' => 'external',
  99. * ]
  100. * ```
  101. *
  102. * Since version 2.0.3 each individual link can override global [[encodeLabels]] param like the following:
  103. *
  104. * ```php
  105. * [
  106. * 'label' => '<strong>Hello!</strong>',
  107. * 'encode' => false,
  108. * ]
  109. * ```
  110. *
  111. */
  112. public $links = [];
  113. /**
  114. * @var string the template used to render each inactive item in the breadcrumbs. The token `{link}`
  115. * will be replaced with the actual HTML link for each inactive item.
  116. */
  117. public $itemTemplate = "<li>{link}</li>\n";
  118. /**
  119. * @var string the template used to render each active item in the breadcrumbs. The token `{link}`
  120. * will be replaced with the actual HTML link for each active item.
  121. */
  122. public $activeItemTemplate = "<li class=\"active\">{link}</li>\n";
  123. /**
  124. * Renders the widget.
  125. */
  126. public function run()
  127. {
  128. if (empty($this->links)) {
  129. return;
  130. }
  131. $links = [];
  132. if ($this->homeLink === null) {
  133. $links[] = $this->renderItem([
  134. 'label' => Yii::t('yii', 'Home'),
  135. 'url' => Yii::$app->homeUrl,
  136. ], $this->itemTemplate);
  137. } elseif ($this->homeLink !== false) {
  138. $links[] = $this->renderItem($this->homeLink, $this->itemTemplate);
  139. }
  140. foreach ($this->links as $link) {
  141. if (!is_array($link)) {
  142. $link = ['label' => $link];
  143. }
  144. $links[] = $this->renderItem($link, isset($link['url']) ? $this->itemTemplate : $this->activeItemTemplate);
  145. }
  146. echo Html::tag($this->tag, implode('', $links), $this->options);
  147. }
  148. /**
  149. * Renders a single breadcrumb item.
  150. * @param array $link the link to be rendered. It must contain the "label" element. The "url" element is optional.
  151. * @param string $template the template to be used to rendered the link. The token "{link}" will be replaced by the link.
  152. * @return string the rendering result
  153. * @throws InvalidConfigException if `$link` does not have "label" element.
  154. */
  155. protected function renderItem($link, $template)
  156. {
  157. $encodeLabel = ArrayHelper::remove($link, 'encode', $this->encodeLabels);
  158. if (array_key_exists('label', $link)) {
  159. $label = $encodeLabel ? Html::encode($link['label']) : $link['label'];
  160. } else {
  161. throw new InvalidConfigException('The "label" element is required for each link.');
  162. }
  163. if (isset($link['template'])) {
  164. $template = $link['template'];
  165. }
  166. if (isset($link['url'])) {
  167. $options = $link;
  168. unset($options['template'], $options['label'], $options['url']);
  169. $link = Html::a($label, $link['url'], $options);
  170. } else {
  171. $link = $label;
  172. }
  173. return strtr($template, ['{link}' => $link]);
  174. }
  175. }