• Yii
  • Yii2之面包屑组件重写以兼容BootStrap4

saonian saonian 01-08 20:53 Edited 224浏览

因为把Yii2的bootstrap组件升级到了4.0beta,所以以前的生成面包屑的组件不能用了。

<?php    
use yii\widgets\Breadcrumbs;    
?>    
<?= Breadcrumbs::widget([    
    'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],    
]) ?>    

还按以前的方式生成面包屑的话生成的html代码是这样式的。

<ul class="breadcrumb"><li><a href="/index.php">首页</a></li>    
<li class="active">登录</li>    
</ul>    

这样的代码在bootstrap4中显示的效果是这样的。

70670934bdec37c920d6c45c7b9dbd0f.png

这样显然是不行的,样式全错了。在bootstrap4中的面包屑应该这样写。

<nav aria-label="breadcrumb">  
  <ol class="breadcrumb">  
    <li class="breadcrumb-item"><a href="#">Home</a></li>  
    <li class="breadcrumb-item active" aria-current="page">Library</li>  
  </ol>  
</nav  

所以我们需要修改一下才行。

于是新建一个Breadcrumbs widget 继承至\yii\widgets\Breadcrumbs,通过阅读源代码得知,需要重写一下属性
$tag, $itemTemplate, $activeItemTemplate

/**  
 * rerite Breadcrumbs widget to fix bt4  
 * @user: luzhuang  
 * @date: 2018/1/8  
 * @time: 下午8:16  
 */  

namespace app\widgets;  

use yii\helpers\Html;  

class Breadcrumbs extends \yii\widgets\Breadcrumbs  
{  
    public $tag = "ol";  

    public $itemTemplate = "<li class='breadcrumb-item'>{link}</li>\n";  

    public $activeItemTemplate = "<li class=\"breadcrumb-item active\" aria-current=\"page\">{link}</li>\n";  

}  

重写完这三个属性之后生成的代码是这样的。

<ol class="breadcrumb"><li class="breadcrumb-item"><a href="/index.php">首页</a></li>  
<li class="breadcrumb-item active" aria-current="page">登录</li>  
</ol>  

显示出来的效果是这样的。

bfd33666de94b8982e6e00a6cfbc33b2.png

虽然好像差不多了,但是和bootstrap的官网文档对比好像还是差点。

少点什么呢?

官方文档中的<ol>xxx</ol>外边有一个<nav aria-label="breadcrumb">包裹着,于是继续阅读源码。

看到下面这行代码。

/**  
 * Renders the widget.  
 */  
public function run()  
{  
    if (empty($this->links)) {  
        return;  
    }  
    $links = [];  
    if ($this->homeLink === null) {  
        $links[] = $this->renderItem([  
            'label' => Yii::t('yii', 'Home'),  
            'url' => Yii::$app->homeUrl,  
        ], $this->itemTemplate);  
    } elseif ($this->homeLink !== false) {  
        $links[] = $this->renderItem($this->homeLink, $this->itemTemplate);  
    }  
    foreach ($this->links as $link) {  
        if (!is_array($link)) {  
            $link = ['label' => $link];  
        }  
        $links[] = $this->renderItem($link, isset($link['url']) ? $this->itemTemplate : $this->activeItemTemplate);  
    }  
    echo Html::tag($this->tag, implode('', $links), $this->options);  
}  

原来是这个run方法输出了html代码,所以获取到这个返回值,照葫芦画瓢也用Html::tag方法在外边包一层nav就行。

但是坑爹的是这个run方法并没有返回值,而是直接echo出了结果。

这改如何是好,机智如我怎么会被这个难道,虽然你不return,但是我还是可以通过其他的方式获取到结果。

/**  
 * rerite Breadcrumbs widget to fix bt4  
 * @user: luzhuang  
 * @date: 2018/1/8  
 * @time: 下午8:16  
 */  

namespace app\widgets;  

use yii\helpers\Html;  

class Breadcrumbs extends \yii\widgets\Breadcrumbs  
{  
    public $wrapper = "nav";  

    public $tag = "ol";  

    public $itemTemplate = "<li class='breadcrumb-item'>{link}</li>\n";  

    public $activeItemTemplate = "<li class=\"breadcrumb-item active\" aria-current=\"page\">{link}</li>\n";  

    public function run()  
    {  
        ob_start();  
        parent::run();  
        $result = ob_get_clean();  
        return Html::tag($this->wrapper, $result, ["aria-label" => "breadcrumb"]);  
    }  
}  

最终生成的代码如下。

<nav aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="/index.php">首页</a></li>  
<li class="breadcrumb-item active" aria-current="page">登录</li>  
</ol></nav>  

ok~ 这下完美了。ob_方法在一些情况下还是很好用滴。

人过留名 雁过留声

saonian

all or nothing, now or never.

话题
回复
粉丝