本文作者:心月

YII2高级版框架搭建完整博客系统教程——自定义组件实现文章列表

心月IT博客 03-17
YII2高级版框架搭建完整博客系统教程——自定义组件实现文章列表摘要:​通过组件的方式实现文章列表,达到重复利用的目的。其他页面需要文章列表的时候只需要调用组件就可以了。

通过组件的方式实现文章列表,达到重复利用的目的。其他页面需要文章列表的时候只需要调用组件就可以了。

1、创建文章列表自定义组件目录

frontend下的widgets 表示存放自定义组件的目录,widgets下的post表示文章列表组件。以后有新的自定义组件只需参照文章列表组件的结构,将其放在frontend/widgets下即可。

views下的index.php为组件获取数据后的数据渲染页面

PostWidget.php为自定义组件类

文章列表自定义组件目录

2、创建文章列表组定义组件类

<?php
namespace frontend\widgets\post;

/**
 * 自定义文章列表组件
 */

use common\models\PostsModel;
use frontend\models\PostsForm;
use yii\base\Widget;
use yii\data\Pagination;
use yii\helpers\Url;
use Yii;

class PostWidget extends Widget
{

    //文章列表的标题
    public $title = '';
    //显示条数
    public $limit = 6;
    //是否显示更多
    public $more = true;
    //是否显示分页
    public $page = false;

    public function run()
    {
        //获取当前页,若没有则默认当前页为1
        $curPage = Yii::$app->request->get('page',1);
        //数据条件,获取已发布数据
        $cond = ['=','is_valid',PostsModel::IS_VALID];
        //获取文章列表数据
        $res = PostsForm::getList($cond, $curPage, $this->limit);
        //设置文章列表属性
        $result['title'] = $this->title?$this->title: '最新文章';
        $result['more'] = Url::to(['posts/index']);
        $result['body'] = $res['data']?$res['data']:[];

        //判断是否显示分页
        if ($this->page){
            $pages = new Pagination(['totalCount'=>$res['count'],'pageSize'=>$res['pageSize']]);
        }
            
        return $this->render('index',['data'=>$result]);
    }
}

文章列表自定义组件到到这也就基本实现了,不过具体的数据获取方法还没有实现,所以接下来就要实现这些获取数据的方法。

文章列表自定义组件类

文章列表自定义组件类

2、组件中数据获取方法的实现

①getList方法实现 (PostForm 中)

/**
 * 获取文章列表
 * @param $cond
 * @param int $curPage
 * @param int $pageSize
 * @param array $orderBy
 * @return mixed
 */
public static function getList($cond, $curPage = 1, $pageSize = 5, $orderBy = ['id'=> SORT_DESC])
{
    $model = new PostsModel();
    //构造查询语句
    //查询字段
    $select = ['id', 'title', 'summary', 'label_img', 'cat_id', 'user_id',
        'user_name', 'is_valid', 'created_at', 'updated_at'];
    $query = $model->find()
        ->select($select)
        ->where($cond)
        ->with('relate.tag','extend')
        ->orderBy($orderBy);

    //获取分页数据
    //因为其他地方也有可能获取列表数据,所以单独用一个获取分页数据的方法来获取文章列表数据
    //为了实现getPage方法的共用性,我们在BaseModel中实现这个方法
    $res = $model -> getPage($query, $curPage, $pageSize);

    //格式化数据(主要格式化tag数据)
    $res['data'] = self::_formatList($res['data']);

    //把获取到的数据返回出去
    return $res;

}

获取文章列表数据

②实现数据格式化方法(PostForm 中)

/**
 * 格式化数据
 * @param $data
 * @return mixed
 */
public static function _formatList($data)
{
    foreach ($data as &$list){
        $list['tags'] = [];
        if (isset($list['relate']) && !empty($list['relate'])){
            foreach ($list['relate'] as $lt){
                $list['tags'][] = $lt['tag']['tag_name'];
            }
            //格式化后把原有的tag关联数据删除
            unset($list['relate']);
        }
    }

    return $data;
}

格式化数据

③在BaseModel中实现获取分页数据方法getPage

public function getPage($query, $curPage = 1, $pageSize = 10, $search = null)
{
    //判断是否搜索,若搜索还需筛选数据
    if ($search)
        $query = $query->andFilerWhere($search);

    //获取总条数 若总条数为0,返回初始配置,若不返回数据会报错
    $data[ 'count'] = $query->count();
    if (!$data['count']){
        return ['count'=>0, 'curPage'=>$curPage, 'pageSize'=>$pageSize,
            'start'=>0, 'end=>0', 'data'=>[]
        ];
    }

    //当前页计算 防止人为输入的页面不存在
    $curPage = (ceil($data['count'])/$pageSize<$curPage)?ceil($data['count'])/$pageSize<$curPage:$curPage;
    //当前页,将数据放入data中返回
    $data['curPage'] = $curPage;
    //每页显示条数
    $data['pageSize'] = $pageSize;
    //数据起始
    $data['start'] = ($curPage-1)*$pageSize+1;
    //数据结束
    $data['end'] = (ceil($data['count'])/$pageSize) == $curPage?$data['count']:$curPage*$pageSize;
    //数据获取
    $data['data'] = $query->offset(($curPage-1)*$pageSize)
        ->limit($pageSize)
        ->asArray()
        ->all();

    return $data;
}

BaseModel中实现获取分页数据方法getPage

数据已经获取到,接下来把数据渲染到自定义文章列表组件的渲染页面index.php

<?php
use yii\helpers\Url;
use yii\widgets\LinkPager;
?>
<div class="panel">
    <div class="panel-title box-title">
        <span><?=$data['title']?></span>
        <?php if($this->context->more):?>
            <span class="pull-right"><a href="<?=$data['more']?>" class="font-12">更多»</a></span>
        <?php endif;?>
    </div>
    <div class="new-list">
        <?php foreach ($data['body'] as $list):?>
            <div class="panel-body border-bottom">
                <div class="row">
                    <div class="col-lg-4 label-img-size">
                        <a href="#" class="post-label">
                            <img src="<?=($list['label_img']?\Yii::$app->params['upload_url'].$list['label_img']:\Yii::$app->params['default_label_img'])?>" alt="<?=$list['title']?>">
                        </a>
                    </div>
                    <div class="col-lg-8 btn-group">
                        <h1><a href="<?=Url::to(['post/detail','id'=>$list['id']])?>"><?=$list['title']?></a></h1>
                        <span class="post-tags">
                        <span class="glyphicon glyphicon-user"></span><a href="<?=Url::to(['member/index','id'=>$list['user_id']])?>"><?=$list['user_name']?></a>&nbsp;
                        <span class="glyphicon glyphicon-time"></span><?=date('Y-m-d',$list['created_at'])?>&nbsp;
                        <span class="glyphicon glyphicon-eye-open"></span><?=isset($list['extend']['browser'])?$list['extend']['browser']:0?>&nbsp;
                        <span class="glyphicon glyphicon-comment"></span><a href="<?=Url::to(['post/detail','id'=>$list['id']])?>"><?=isset($list['extend']['comment'])?$list['extend']['comment']:0?></a>
                    </span>
                        <p class="post-content"><?=$list['summary']?></p>
                        <a href="<?=Url::to(['post/detail','id'=>$list['id']])?>"><button class="btn btn-warning no-radius btn-sm pull-right">阅读全文</button></a>
                    </div>
                </div>
                <div class="tags">
                    <?php if(!empty($list['tags'])):?>
                        <span class="fa fa-tags"></span>
                        <?php foreach ($list['tags'] as $lt):?>
                            <a href="#"><?=$lt?></a>,
                        <?php endforeach;?>
                    <?php endif;?>
                </div>
            </div>
        <?php endforeach;?>
    </div>
    <?php if($this->context->page):?>
        <div class="page"><?=LinkPager::widget(['pagination' => $data['page']]);?></div>
    <?php endif;?>
</div>

组件数据渲染

不过这里有两个数据需要配置 'upload_url' (图片路径前缀),'default_label_img',当文章没有缩率图时显示的默认图片

'upload_url' => 'http://frontend.yii2.com',
'default_label_img' => '/statics/images/default.png',

默认配置设置

文章列表自定义组件就算完成了,接下来就是调用,文章列表渲染页调用,其他页面调用文章列表自定义组件列表方法也是一样的

<?php

use frontend\widgets\post\PostWidget;
use yii\base\Widget;
?>

<?=PostWidget::widget()?>

文章列表自定义组件调用

文章列表页需要添加的css样式(放到site.css页面即可),若不加css样式最后的页面显示可能会有点丑。

.panel-body h1 {
    font-size: 18px;
    height: 30px;
    line-height: 30px;
    margin: 0;
    overflow: hidden;
}

.post-label {
    background-color: #fff;
    border: 1px solid #ddd;
    display: block;
    line-height: 1.42857;
    padding: 4px;
    transition: border 0.2s ease-in-out 0s;
	border-radius: 0;
    margin-bottom: 5px;
    position: relative;
}

.post-label > img {
    margin-left: auto;
    margin-right: auto;
    display: block;
    height: 150px;
    width: 100%;
}

.post-tags {
    color: #999;
    font-size: 12px;
}

.post-tags span {
    margin-right: 4px;
}

.post-tags a {
    color: #999;
}

.tags {
    font-size: 12px;
    margin-left: 2px;
}

.font-12 {
    font-size: 12px;
}

最后的文章列表调用效果:

文章列表组件调用效果


文章版权及转载声明:

本文由 心月IT技术博客 博主整理于 03-17
若转载请注明原文及出处:https://www.xinyueseo.com/yii/192.html

分享到:
赞(
发表评论
快捷输入:

验证码

    评论列表 (有 0 条评论,人围观)参与讨论