#1、首页显示文章和标签
#修改 view/index.blade.php
@extends('_layouts.default') @section('main') <div class="am-g am-g-fixed"> <div class="am-u-md-8"> @foreach ($articles as $article) <article class="blog-main"> <h3 class="am-article-title blog-title"> <a href="{{ URL::route('article.show', $article->id) }}">{{{ $article->title }}}</a> </h3> <h4 class="am-article-meta blog-meta"> by <a href="#">{{{ $article->user->nickname }}}</a> posted on {{ $article->created_at->format('Y/m/d H:i') }} under @foreach ($article->tags as $tag) <a href="#" style="color: #fff;" class="am-badge am-badge-success am-radius">{{ $tag->name }}</a> @endforeach </h4> <div class="am-g"> <div class="am-u-sm-12"> @if ($article->summary) <p>{{ $article->summary }}</p> @endif <hr class="am-article-divider"/> </div> </div> </article> @endforeach </div> <div class="am-u-md-4 blog-sidebar"> <br/> <div class="am-panel-group"> <section class="am-panel am-panel-default"> <div class="am-panel-hd"><span class="am-icon-tags"></span> Tags</div> <ul class="am-list"> @for ($i = 0, $len = count($tags); $i < $len; $i++) <li> <a href="#">{{ $tags[$i]->name }} @if ($i == 0) <span class="am-fr am-badge am-badge-danger am-round">{{ $tags[$i]->count }}</span> @elseif ($i == 1) <span class="am-fr am-badge am-badge-warning am-round">{{ $tags[$i]->count }}</span> @elseif ($i == 2) <span class="am-fr am-badge am-badge-success am-round">{{ $tags[$i]->count }}</span> @else <span class="am-fr am-badge am-round">{{ $tags[$i]->count }}</span> @endif </a> </li> @endfor </ul> </section> </div> </div> </div> @stop
#public/custom.css 增加
@media only screen and (min-width: 641px) { .blog-sidebar { font-size: 1.4rem; } } .blog-main { padding: 20px 0; } .blog-title { margin: 10px 0 20px 0; } .blog-meta { font-size: 14px; margin: 10px 0 20px 0; color: #222; } .blog-meta a { color: #27ae60; }
Route::get('/', function() { $articles = Article::with('user', 'tags')->orderBy('created_at', 'desc')->paginate(10); $tags = Tag::where('count', '>', '0')->orderBy('count', 'desc')->orderBy('updated_at', 'desc')->take(10)->get(); return View::make('index')->with('articles', $articles)->with('tags', $tags); });
上面Article::with()使用了预加载,可以减少查询次数。
#2、修改用户主页
#在导航栏nav.blade.php 添加 My Articles 按钮
<div class="am-topbar-right"> <a href="{{ URL::to('user/'. Auth::id() . '/articles') }}" class="am-btn am-btn-primary am-topbar-btn am-btn-sm topbar-link-btn"><span class="am-icon-list"></span> My Articles</a> </div>
#修改home.blade.php
@extends('_layouts.default') @section('main') <div class="am-g am-g-fixed blog-g-fixed"> <div class="am-u-sm-12"> <table class="am-table am-table-hover am-table-striped "> <thead> <tr> <th>Title</th> <th>Tags</th> @if ($user->id == Auth::id()) <th>Managment</th> @endif </tr> </thead> <tbody> @foreach ($articles as $article) <tr> <td><a href="{{ URL::route('article.show', $article->id) }}">{{{ $article->title }}}</a></td> <td> @foreach ($article->tags as $tag) <span class="am-badge am-badge-success am-radius">{{ $tag->name }}</span> @endforeach </td> @if ($user->id == Auth::id()) <td> <a href="{{ URL::to('article/'. $article->id . '/edit') }}" class="am-btn am-btn-xs am-btn-primary"><span class="am-icon-pencil"></span> Edit</a> {{ Form::open(array('url' => 'article/' . $article->id, 'method' => 'DELETE', 'style' => 'display: inline;')) }} <button type="button" class="am-btn am-btn-xs am-btn-danger" id="delete{{ $article->id }}"><span class="am-icon-remove"></span> Delete</button> {{ Form::close() }} </td> @endif </tr> @endforeach </tbody> </table> </div> </div> <div class="am-modal am-modal-confirm" tabindex="-1" id="my-confirm"> <div class="am-modal-dialog"> <div class="am-modal-bd"> </div> <div class="am-modal-footer"> <span class="am-modal-btn" data-am-modal-cancel>No</span> <span class="am-modal-btn" data-am-modal-confirm>Yes</span> </div> </div> </div> <script> $(function() { $('[id^=delete]').on('click', function() { $('.am-modal-bd').text('Sure you want to delete it?'); $('#my-confirm').modal({ relatedTarget: this, onConfirm: function(options) { $(this.relatedTarget).parent().submit(); }, onCancel: function() { } }); }); }); </script> @stop
php artisan generate:controller UserController
public function articles(User $user) { return View::make('home')->with('user', $user)->with('articles', Article::with('tags')->where('user_id', '=', $user->id)->orderBy('created_at', 'desc')->get()); }
Route::get('user/{user}/articles', 'UserController@articles');
#修改路由
Route::get('home', array('before' => 'auth', function() { return View::make('home')->with('user', Auth::user())->with('articles', Article::with('tags')->where('user_id', '=', Auth::id())->orderBy('created_at', 'desc')->get()); }));#views/index.blade.php 添加作者链接
<a href="{{ URL::to('user/' . $article->user->id . '/articles') }}">{{{ $article->user->nickname }}}</a>
<a href="{{ URL::to('user/' . $article->user->id . '/articles') }}" style="cursor: pointer;">{{{ $article->user->nickname }}}</a>
#在app 创建Blog (放置扩展类) ,在其中新建分页文件 PaginationPresenter.php,修改为
class PaginationPresenter extends Illuminate\Pagination\Presenter { public function getActivePageWrapper($text) { return '<li class="am-active"><a href="">'.$text.'</a></li>'; } public function getDisabledTextWrapper($text) { return '<li class="am-disabled"><a href="">'.$text.'</a></li>'; } public function getPageLinkWrapper($url, $page, $rel = null) { return '<li><a href="'.$url.'">'.$page.'</a></li>'; } }#在
composer.josn中的autoload classmap
添加"app/Blog"
composer dump-autoload
#创建分类视图
php artisan generate:view pagination
#修改pagination.blade.php
<ul class="am-pagination am-pagination-centered"> {{ with(new PaginationPresenter($paginator))->render() }} </ul>
#修改app/config/view.php 中的pagination 的值为 pagination 在routes.php中Route::get('/')内paginate()的参数就是指定每页显示的数量,由于我文章比较少,暂时把它设为2,最后在views/index.blade.php中文章显示之后添加{{ $articles->links() }}
#4、修改文章视图
#在ArticleController.php 新增过滤器
public function canOperation($route, $request) { if (!(Auth::user()->is_admin or Auth::id() == Article::find(Route::input('article'))->user_id)) { return Redirect::to('/'); } }
$this->beforeFilter('csrf', array('only' => array('store', 'update', 'destroy'))); $this->beforeFilter('@canOperation', array('only' => array('edit', 'update', 'destroy')));
#创建文章修改视图
php artisan generate:view articles.edit
#修改视图articles/edit.blade.php
@extends('_layouts.default') @section('main') <div class="am-g am-g-fixed"> <div class="am-u-sm-12"> <h1>Edit Article</h1> <hr/> @if ($errors->has()) <div class="am-alert am-alert-danger" data-am-alert> <p>{{ $errors->first() }}</p> </div> @endif {{ Form::model($article, array('url' => URL::route('article.update', $article->id), 'method' => 'PUT', 'class' => "am-form")) }} <div class="am-form-group"> {{ Form::label('title', 'Title') }} {{ Form::text('title', Input::old('title')) }} </div> <div class="am-form-group"> {{ Form::label('content', 'Content') }} {{ Form::textarea('content', Input::old('content'), array('rows' => '20')) }} <p class="am-form-help"> <button id="preview" type="button" class="am-btn am-btn-xs am-btn-primary"><span class="am-icon-eye"></span> Preview</button> </p> </div> <div class="am-form-group"> {{ Form::label('tags', 'Tags') }} {{ Form::text('tags', Input::old('tags')) }} <p class="am-form-help">Separate multiple tags with a comma ","</p> </div> <p><button type="submit" class="am-btn am-btn-success"> <span class="am-icon-pencil"></span> Modify</button> </p> {{ Form::close() }} </div> </div> <div class="am-popup" id="preview-popup"> <div class="am-popup-inner"> <div class="am-popup-hd"> <h4 class="am-popup-title"></h4> <span data-am-modal-close class="am-close">×</span> </div> <div class="am-popup-bd"> </div> </div> </div> <script> $(function() { $('#preview').on('click', function() { $('.am-popup-title').text($('#title').val()); $.post('preview', {'content': $('#content').val()}, function(data, status) { $('.am-popup-bd').html(data); }); $('#preview-popup').modal(); }); }); </script> @stop
Route::post('article/{id}/preview', array('before' => 'auth', 'uses' => 'ArticleController@preview'));
#修改ArticleController.php 编辑一面显示
public function edit($id) { $article = Article::with('tags')->find($id); $tags = ''; for ($i = 0, $len = count($article->tags); $i < $len; $i++) { $tags .= $article->tags[$i]->name . ($i == $len - 1 ? '' : ','); } $article->tags = $tags; return View::make('articles.edit')->with('article', $article); }
#修改ArticleController.php
public function update($id) { $rules = [ 'title' => 'required|max:100', 'content' => 'required', 'tags' => array('required', 'regex:/^\w+$|^(\w+,)+\w+$/'), ]; $validator = Validator::make(Input::all(), $rules); if ($validator->passes()) { $article = Article::with('tags')->find($id); $article->update(Input::only('title', 'content')); $resolved_content = Markdown::parse(Input::get('content')); $article->resolved_content = $resolved_content; $tags = array_unique(explode(',', Input::get('tags'))); if (str_contains($resolved_content, '<p>')) { $start = strpos($resolved_content, '<p>'); $length = strpos($resolved_content, '</p>') - $start - 3; $article->summary = substr($resolved_content, $start + 3, $length); } elseif (str_contains($resolved_content, '</h')) { $start = strpos($resolved_content, '<h'); $length = strpos($resolved_content, '</h') - $start - 4; $article->summary = substr($resolved_content, $start + 4, $length); } $article->save(); foreach ($article->tags as $tag) { if (($index = array_search($tag->name, $tags)) !== false) { unset($tags[$index]); } else { $tag->count--; $tag->save(); $article->tags()->detach($tag->id); } } foreach ($tags as $tagName) { $tag = Tag::whereName($tagName)->first(); if (!$tag) { $tag = Tag::create(array('name' => $tagName)); } $tag->count++; $article->tags()->save($tag); } return Redirect::route('article.show', $article->id); } else { return Redirect::route('article.edit', $id)->withInput()->withErrors($validator); } }
#修改ArticleController.php
public function destroy($id) { $article = Article::find($id); foreach ($article->tags as $tag) { $tag->count--; $tag->save(); $article->tags()->detach($tag->id); } $article->delete(); return Redirect::to('home'); }
代码:$ git clone https://github.com/shiyanlou/laravel-blog-4.git
参照:https://www.shiyanlou.com/courses/document/414