[ * // the item contains only the image * '', * // equivalent to the above * ['content' => ''], * // the item contains both the image and the caption * [ * 'content' => '', * 'caption' => '

This is title

This is the caption text

', * 'options' => [...], * ], * ] * ]); * ``` * * @see http://getbootstrap.com/javascript/#carousel * @author Antonio Ramirez * @since 2.0 */ class Carousel extends Widget { /** * @var array|boolean the labels for the previous and the next control buttons. * If false, it means the previous and the next control buttons should not be displayed. */ public $controls = ['‹', '›']; /** * @var boolean * If false carousel indicators (
    tag with anchors to items) should not be displayed. */ public $showIndicators = true; /** * @var array list of slides in the carousel. Each array element represents a single * slide with the following structure: * * ```php * [ * // required, slide content (HTML), such as an image tag * 'content' => '', * // optional, the caption (HTML) of the slide * 'caption' => '

    This is title

    This is the caption text

    ', * // optional the HTML attributes of the slide container * 'options' => [], * ] * ``` */ public $items = []; /** * Initializes the widget. */ public function init() { parent::init(); Html::addCssClass($this->options, 'carousel'); } /** * Renders the widget. */ public function run() { echo Html::beginTag('div', $this->options) . "\n"; echo $this->renderIndicators() . "\n"; echo $this->renderItems() . "\n"; echo $this->renderControls() . "\n"; echo Html::endTag('div') . "\n"; $this->registerPlugin('carousel'); } /** * Renders carousel indicators. * @return string the rendering result */ public function renderIndicators() { if ($this->showIndicators === false) { return ''; } $indicators = []; for ($i = 0, $count = count($this->items); $i < $count; $i++) { $options = ['data-target' => '#' . $this->options['id'], 'data-slide-to' => $i]; if ($i === 0) { Html::addCssClass($options, 'active'); } $indicators[] = Html::tag('li', '', $options); } return Html::tag('ol', implode("\n", $indicators), ['class' => 'carousel-indicators']); } /** * Renders carousel items as specified on [[items]]. * @return string the rendering result */ public function renderItems() { $items = []; for ($i = 0, $count = count($this->items); $i < $count; $i++) { $items[] = $this->renderItem($this->items[$i], $i); } return Html::tag('div', implode("\n", $items), ['class' => 'carousel-inner']); } /** * Renders a single carousel item * @param string|array $item a single item from [[items]] * @param integer $index the item index as the first item should be set to `active` * @return string the rendering result * @throws InvalidConfigException if the item is invalid */ public function renderItem($item, $index) { if (is_string($item)) { $content = $item; $caption = null; $options = []; } elseif (isset($item['content'])) { $content = $item['content']; $caption = ArrayHelper::getValue($item, 'caption'); if ($caption !== null) { $caption = Html::tag('div', $caption, ['class' => 'carousel-caption']); } $options = ArrayHelper::getValue($item, 'options', []); } else { throw new InvalidConfigException('The "content" option is required.'); } Html::addCssClass($options, 'item'); if ($index === 0) { Html::addCssClass($options, 'active'); } return Html::tag('div', $content . "\n" . $caption, $options); } /** * Renders previous and next control buttons. * @throws InvalidConfigException if [[controls]] is invalid. */ public function renderControls() { if (isset($this->controls[0], $this->controls[1])) { return Html::a($this->controls[0], '#' . $this->options['id'], [ 'class' => 'left carousel-control', 'data-slide' => 'prev', ]) . "\n" . Html::a($this->controls[1], '#' . $this->options['id'], [ 'class' => 'right carousel-control', 'data-slide' => 'next', ]); } elseif ($this->controls === false) { return ''; } else { throw new InvalidConfigException('The "controls" property must be either false or an array of two elements.'); } } }