博客内容

博客内容

博客内容的展示是一个博客的核心功能,本节课程主要的功能分为:文章列表、文章详情等相关功能开发。

文章列表

博客列表页

文章列表的样式可以参考首页,主要实现的功能为通过模型获取文章分页数据,但此处要添加一个分页挂件 Pagination 在页面渲染即可生成分页,通过 yii2 的挂件配合,实现文章列表功能就非常简单了。打开 frontend/controller/ArticleController 添加如下代码:

use Yii;
use common\models\Article;
use yii\data\Pagination;
use yii\web\Controller;
/**
 * 文章列表页
 *
 * @return string
 */
public function actionIndex()
{
    //定义每页显示条数
    $pageSize = 10;

    //获取当前页码
    $curPage = Yii::$app->request->get('page',1);

    //计算查询的 offset 值
    $offset = ($curPage-1) * $pageSize;

    //数据查询query
    $query = Article::find()->where(['is_valid' => 1]);
    $countQuery = clone $query;

    //获取当页文章数据
    $article = $query->with('category', 'statistics')
        ->orderBy(['id' => SORT_DESC])
        ->offset($offset)
        ->limit($pageSize)
        ->asArray()
        ->all();

    //分页挂件
    $pages = new Pagination(['totalCount' => $countQuery->count(), 'pageSize' => $pageSize ]);

    return $this->render('index',[
        'article' => $article,
        'pages' => $pages
    ]);
}

然后打开 frontend/views/article/index.php 在页面中将获取的到数据进行渲染:

<?php foreach ($article as $item):?>
    <div class="blogs" data-scroll-reveal="enter bottom over 1s" >
        <h3 class="blogtitle"><a href="<?=Url::to(['article/detail','id'=>$item['id']])?>" target="_blank"><?=$item['title']?></a></h3>
        <span class="blogpic"><a href="<?=Url::to(['article/detail','id'=>$item['id']])?>" title=""><img src="<?=Yii::$app->params['qiniu']['domain'].'/'.$item['image_url']?>" alt=""></a></span>
        <p class="blogtext"><?=mb_substr($item['content'],0,150)?></p>
        <div class="bloginfo">
            <ul>
                <li class="author"><a href="/"><i class="fa fa-user"></i> <?=$item['author']?></a></li>
                <li class="lmname"><a href="/"><i class="fa fa-list"></i> <?=$item['category']['name']?></a></li>
                <li class="timer"><i class="fa fa-clock-o"></i> <?=$item['created_at']?></li>
                <li class="view"><i class="fa fa-eye"></i> <?=isset($item['statistics']['visit'])?$item['statistics']['visit']:0?></li>
            </ul>
        </div>
    </div>
<?php endforeach;?>

分页挂件的实现:

<div class="page"><?=\yii\widgets\LinkPager::widget(['pagination' => $pages]);?></div>

此处如果分页不显示是因为之前录入的数据只有10条,当前页显示10条,只有一页,分页挂件就会隐藏,此时只需要添加更多的 demo 数据或者减少每页显示条数即可

边栏部分,我们制作了边栏挂件,这里也可以重复使用:

<div class="sidebar">
    <?=\common\widgets\sidebar\SidebarWidget::widget()?>
</div>

如此,我们的 博客列表页 就开发完成了,效果如下:

时间史(点滴)

文章时间史的数据获取与文章列表页基本一致,除了此处不需要关联查询访问统计表和分类表,就不在赘述了,直接贴代码:

/**
 * 文章时间史
 * 
 * @return string
 */
public function actionTime()
{
    //定义每页显示条数
    $pageSize = 20;

    //获取当前页码
    $curPage = Yii::$app->request->get('page',1);

    //计算查询的 offset 值
    $offset = ($curPage-1) * $pageSize;

    //数据查询query
    $query = Article::find()->where(['is_valid' => 1]);
    $countQuery = clone $query;

    //获取当页文章数据
    $article = $query
        ->orderBy(['id' => SORT_DESC])
        ->offset($offset)
        ->limit($pageSize)
        ->asArray()
        ->all();

    //分页挂件
    $pages = new Pagination(['totalCount' => $countQuery->count(), 'pageSize' => $pageSize ]);

    return $this->render('index',[
        'article' => $article,
        'pages' => $pages
    ]);
}

页面数据渲染:

<div class="row">
    <div class="col-lg-12 top-nav">
        <h1 class="t_nav"><span>时光飞逝,机会就在我们眼前,何时找到了灵感,就要把握机遇,我们需要智慧和勇气去把握机会。</span><a href="/" class="n1">网站首页</a><a href="/" class="n2">时间点滴</a></h1>
    </div>

    <div class="col-lg-12">
        <div class="timebox">
            <ul id="list" style="display:block;">
                <?php foreach ($article as $item):?>
                <li><span><?=date('Y-m-d',strtotime($item['created_at']));?></span><a href="<?=\yii\helpers\Url::to(['article/detail','id'=>$item['id']])?>" title="<?=$item['title']?>"><?=$item['title']?></a></li>
                <?php endforeach;?>
            </ul>

            <div class="page"><?=\yii\widgets\LinkPager::widget(['pagination' => $pages]);?></div>
        </div>
    </div>
</div>

效果如下:

文章详情

文章详情页的开发非常简单,先根据 文章id 获取对应的文章信息,然后在页面上做渲染。然后在详情页做一个访问统计,用户每次访问,浏览量+1,写入统计表。

思路:如果考虑性能问题,可以对文章详情做缓存,每次访问读取缓存,文章创建和修改更新缓存即可。访问统计也可以先用 redis 统计,写个定时任务定期同步到统计表。

对此,相应的代码如下:

先在统计模型 Statistics 中添加文章统计通用方法:

/**
 * 更新文章统计
 */
public function upCounter($cond, $attribute, $num)
{
    $counter = $this->findOne($cond);
    if(!$counter){
        $this->setAttributes($cond);
        $this->$attribute = $num;
        $this->save();
    }else{
        $countData[$attribute] = $num;
        $counter->updateCounters($countData);
    }

}

然后在 frontend/controller/ArticleController 的 actionDetail 中添加如下代码:

/**
 * 文章详情页
 *
 * @return string
 */
public function actionDetail($id)
{
    //获取文章详情
    $article = Article::find()
        ->where(['id'=>$id,'is_valid'=>1])
        ->with('statistics', 'category')
        ->asArray()
        ->one();

    //更新访问统计
    $model = new Statistics();
    $model->upCounter(['article_id' => $article['id']], 'visit', 1);

    return $this->render('detail',[
        'article' => $article,
    ]);
}

页面渲染如下,右边的边栏依旧使用边栏挂件即可:

<?php
/**
 * 文章详情页
 *
 * @author huangxianan <xianan_huang@163.com>
 * Date: 2018/6/1
 */

$this->title = $article['title'].' - hyBlog';
?>

<div class="row">
    <div class="col-lg-12 top-nav">
        <h1 class="t_nav"><span>您现在的位置是:首页 &gt; 奇文欣赏 &gt; <?=$article['title']?></span><a href="/" class="n1">网站首页</a><a href="/" class="n2">奇文欣赏</a></h1>
    </div>
    <div class="col-lg-8">
        <div class="infosbox">
            <div class="newsview">
                <h3 class="news_title"><?=$article['title']?></h3>
                <div class="bloginfo">
                    <ul>
                        <li class="author"><a href="/"><i class="fa fa-user"></i> <?=$article['author']?></a></li>
                        <li class="lmname"><a href="/"><i class="fa fa-list"></i> <?=$article['category']['name']?></a></li>
                        <li class="timer"><i class="fa fa-clock-o"></i> <?=$article['created_at']?></li>
                        <li class="view"><i class="fa fa-eye"></i> <?=$article['statistics']['visit']?></li>
                    </ul>
                </div>

                <div class="markdown-content">
                    <?=\kartik\markdown\Markdown::convert($article['content'])?>
                </div>
            </div>
        </div>
    </div>
    <div class="col-lg-4">
        <div class="sidebar">
            <?=\common\widgets\sidebar\SidebarWidget::widget()?>
        </div>
    </div>
</div>

如此,博客文章详情页面就开发完成了,效果如下:

文章预览

在管理后台开发教程中预留了一个文章预览的功能未开发,只是在文章列表中添加了一个预览的按钮。现在就来实现文章预览功能,其实预览功能很简单,跟文章详情页的功能基本一致,我们只需要重新创建一个 actionPreview 代码也拷贝文章详情控制器即可,唯一的差别就是查询语句中减少一个条件 'is_valid'=>1,目的就是即使未发布的内容我们也可以进行预览。此处只是做了简单的处理,提供思路,更加严谨预览的功能可以增加更多的限制。代码如下:

/**
 * 文章预览
 *
 * @return string
 */
public function actionPreview($id)
{
    //获取文章详情
    $article = Article::find()
        ->where(['id'=>$id])
        ->with('statistics', 'category')
        ->asArray()
        ->one();

    //更新访问统计
    $model = new Statistics();
    $model->upCounter(['article_id' => $article['id']], 'visit', 1);

    return $this->render('detail',[
        'article' => $article,
    ]);
}
上一篇
yii2 入门教程 - 博客系统搭建
第1章. 基本信息
第2章. 开发环境部署