用 10 分鐘在 Cloud9 開發一個 Laravel 5 的 Blog
Cloud9是一個雲端Web開發平台,它提供了一些開發環境給我們(例如安裝了PHP、Ruby、Python等),讓我們省卻配置伺服器及開發環境的時間,可以立即開發Web App。Cloud9 是免費的,每個開發環境有1個CPU、512MB RAM 及 2GB HDD,對小型 project 是夠用的,很適合用來學習各種 Web App 的開發。
選擇開發環境
等待 Cloud9 建立開發環境
建立完畢便進入了我們的開發環境
最後是取得最新版本的 Laravel(筆者安裝的版本是 5.2)
至此 Laravel 5 已成功安裝,看看左邊已經多了 Laravel framework 的檔案
終於可以正式開發網誌網頁應用程式了。
請注意,本系列教學只會以最精簡的方式列出完成開發時必要的步驟,並在適當的地方加插圖片輔助,希望讀者能在最短時間親自完成教學。因此,當中的說明或解釋將會省略,如欲了解,請參考原文 Simple blog application in laravel 5。 這個日誌會有以下功能:
1. 任何人都可登入/註冊
2. 用戶可分類為「admin」、「author」或「subscriber」
3. 「author」可以撰寫/更新/刪除帖子
4. 「admin」擁有網站全部存取權限及可以閱讀/撰寫/更新/刪除任何帖子
5. 任何人都可閱讀帖子
6. 用戶可以(登入後)在帖子內留言
完成品如下圖所示,可到示範網站參看:
這個教學將分作 5 部份:
1) Setup database
- Connect with mysql database
- Create posts and comments tables
2) Make routes and models
- Routes
- Create post model
- Create comment model
- Create User model
3) Controllers
- PostController
- CommentController
4) Build front end
- Customize app.blade.php
- make home view
- Create posts
- Show posts
- Edit posts
5) Add tinymce and Make user profile
- Add tinymce to posts
- Make profile backend
- View for profile
Cloud9 IDE是一個免費的在線集成開發環境,支持四十多種程式語言,例如 PHP、Ruby、Python、Go、JavaScript(包括Node.js)等。它可以使開發者在一個事先安裝好的環境中快速進入開發、與其他人協作並且在Web開發中做到實時預覽和瀏覽器兼容性測試等。
- Wiki
我們會用一個熱門的 PHP 框架 - Laravel(版本:5.2),在 Cloud9 建立一個簡單的 Blog 網站應用程式,所以請先到 Cloud9 註冊戶口。 開完戶口就可以立即建立開發環境選擇開發環境
等待 Cloud9 建立開發環境
建立完畢便進入了我們的開發環境
安裝 Laravel 5
接下來會安裝最熱門的 PHP Framework - Laravel 5
在 Terminal 輸入以下指令(可以一次過複製以下指令並在 Terminal 貼上)rm README.md php.ini hello-world.php sudo composer self-update composer create-project laravel/laravel ./laravel --prefer-dist shopt -s dotglob mv laravel/* ./ rm -rf laravel因為 Laravel 會提供 public 資料夾 的檔案給 Client,所以我們要(透過一個文字編緝器nano)修改 Apache Config
sudo nano /etc/apache2/sites-enabled/001-cloud9.conf把
DocumentRoot /home/ubuntu/workspace改為
DocumentRoot /home/ubuntu/workspace/public改完請按 F2 儲存,然後 'Y' 及 'Enter'。
最後是取得最新版本的 Laravel(筆者安裝的版本是 5.2)
sudo composer update
至此 Laravel 5 已成功安裝,看看左邊已經多了 Laravel framework 的檔案
終於可以正式開發網誌網頁應用程式了。
請注意,本系列教學只會以最精簡的方式列出完成開發時必要的步驟,並在適當的地方加插圖片輔助,希望讀者能在最短時間親自完成教學。因此,當中的說明或解釋將會省略,如欲了解,請參考原文 Simple blog application in laravel 5。 這個日誌會有以下功能:
1. 任何人都可登入/註冊
2. 用戶可分類為「admin」、「author」或「subscriber」
3. 「author」可以撰寫/更新/刪除帖子
4. 「admin」擁有網站全部存取權限及可以閱讀/撰寫/更新/刪除任何帖子
5. 任何人都可閱讀帖子
6. 用戶可以(登入後)在帖子內留言
完成品如下圖所示,可到示範網站參看:
這個教學將分作 5 部份:
1) Setup database
- Connect with mysql database
- Create posts and comments tables
2) Make routes and models
- Routes
- Create post model
- Create comment model
- Create User model
3) Controllers
- PostController
- CommentController
4) Build front end
- Customize app.blade.php
- make home view
- Create posts
- Show posts
- Edit posts
5) Add tinymce and Make user profile
- Add tinymce to posts
- Make profile backend
- View for profile
Part 1: 建立數據庫
首先我們會建立數據庫表格用作儲存資料,當中會用到 migrations 及 schema builder。 建立數據庫表格前要先配置好連接數據庫的資訊,請在應用程式的根目錄(root)找到 .env (.env是一個隱藏檔案),並更新連接數據庫的資訊DB_HOST=localhost DB_DATABASE=your_database_name DB_USERNAME=database_username DB_PASSWORD=database_passwordCloud9用戶可參考以下配置,只需把 DB_USERNAME 改為你的登入名稱就可以:
DB_HOST=localhost DB_DATABASE=c9 DB_USERNAME=amzfree DB_PASSWORD=到 blog >> config >> database.php , 找到 default, 改為
'default' => env('DB_CONNECTION', 'mysql'),改完請儲存所有檔案 在 Terminal 輸入以下程式碼安裝 MySQL:
mysql-ctl install或者輸入以下程式碼安裝 MySQL:
mysql-ctl cli安裝完畢後退出 MySQL
exit現在用 migrations
php artisan make:migration posts php artisan make:migration comments留意 blog >> database >> migrations 多了 2 個檔案
建立 posts 表格
打開 建立時間_posts.php,清除所有程式碼並貼上以下(用作在數據庫建立一個名為 posts 的表格的)程式碼<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class Posts extends Migration { /** * Run the migrations. * * @return void */ public function up() { // blog table Schema::create('posts', function(Blueprint $table) { $table->increments('id'); $table -> integer('author_id') -> unsigned() -> default(0); $table->foreign('author_id') ->references('id')->on('users') ->onDelete('cascade'); $table->string('title')->unique(); $table->text('body'); $table->string('slug')->unique(); $table->boolean('active'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { // drop blog table Schema::drop('posts'); } }Migration 的作用是數據庫版本控制(database version control),原理與程式碼版本控制一樣,Migration 有 up() 和 down() 2 個 function,migration 執行的時候會執行up(),down() 則是 up() 的相反,還原 up() 所做過的。例如這裡的 up() 我們 create 了 posts 的 table ,down() 的時候便要把 posts 這個 table drop 走。 Schema 是另一個在建立/修改數據庫表格會用到的Class,create() function 有 2 個 arguments,第 1 個是數據庫名稱,另一個是開 column 的 closure。$table 是這個表格的 instance 。
建立 comments 表格
同樣地將以下程式碼貼到 建立時間_comments.php<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class Comments extends Migration { /** * Run the migrations. * * @return void */ public function up() { //id, on_blog, from_user, body, at_time Schema::create('comments', function(Blueprint $table) { $table->increments('id'); $table -> integer('on_post') -> unsigned() -> default(0); $table->foreign('on_post') ->references('id')->on('posts') ->onDelete('cascade'); $table -> integer('from_user') -> unsigned() -> default(0); $table->foreign('from_user') ->references('id')->on('users') ->onDelete('cascade'); $table->text('body'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { // drop comment Schema::drop('comments'); } }
User 表格:
User 表格的 migration 已經存在,但我們想增加用戶身份角色,所以要加多一行:$table->string('password', 60); // add this one line $table->enum('role',['admin','author','subscriber'])->default('author'); $table->rememberToken();儲存所有更改 最後是 generate 表格,在 Terminal 輸入:
php artisan migrate數據庫設置完成
Part 2: Route 路由控制 與 Model
現在是管理 blog 的路徑,我們會用 Route 類別將 url 與 Controller 聯繫,Route 類別有 get(), post(), delete(), put(), all() 及 match() 共6個 function,我們只會用到 get() 和 post()。把 app/Http/routes.php 改成以下程式碼:<?php /* |-------------------------------------------------------------------------- | Application Routes |-------------------------------------------------------------------------- | | Here is where you can register all of the routes for an application. | It's a breeze. Simply tell Laravel the URIs it should respond to | and give it the controller to call when that URI is requested. | */ Route::get('/','PostController@index'); Route::get('/home',['as' => 'home', 'uses' => 'PostController@index']); //authentication Route::controllers([ 'auth' => 'Auth\AuthController', 'password' => 'Auth\PasswordController', ]); // check for logged in user Route::group(['middleware' => ['auth']], function() { // show new post form Route::get('new-post','PostController@create'); // save new post Route::post('new-post','PostController@store'); // edit post form Route::get('edit/{slug}','PostController@edit'); // update post Route::post('update','PostController@update'); // delete post Route::get('delete/{id}','PostController@destroy'); // display user's all posts Route::get('my-all-posts','UserController@user_posts_all'); // display user's drafts Route::get('my-drafts','UserController@user_posts_draft'); // add comment Route::post('comment/add','CommentController@store'); // delete comment Route::post('comment/delete/{id}','CommentController@distroy'); }); //users profile Route::get('user/{id}','UserController@profile')->where('id', '[0-9]+'); // display list of posts Route::get('user/{id}/posts','UserController@user_posts')->where('id', '[0-9]+'); // display single post Route::get('/{slug}',['as' => 'post', 'uses' => 'PostController@show'])->where('slug', '[A-Za-z0-9-_]+');
建立 Model
1. Posts
現在會建立 Model。在 app 資料夾新增 2 個檔案:Posts.php 及 Comments.php。在 Posts.php 貼上以下程式碼:<?php namespace App; use Illuminate\Database\Eloquent\Model; // instance of Posts class will refer to posts table in database class Posts extends Model { //restricts columns from modifying protected $guarded = []; // posts has many comments // returns all comments on that post public function comments() { return $this->hasMany('App\Comments','on_post'); } // returns the instance of the user who is author of that post public function author() { return $this->belongsTo('App\User','author_id'); } }
2) Comments
同樣原理在 Comments.php 貼上以下程式碼:<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comments extends Model { //comments table in database protected $guarded = []; // user who has commented public function author() { return $this->belongsTo('App\User','from_user'); } // returns post of any comment public function post() { return $this->belongsTo('App\Posts','on_post'); } }
3) User
把 app/User.php 改成:<?php namespace App; use Illuminate\Auth\Authenticatable; use Illuminate\Database\Eloquent\Model; use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; class User extends Model implements AuthenticatableContract, CanResetPasswordContract { use Authenticatable, CanResetPassword; /** * The database table used by the model. * * @var string */ protected $table = 'users'; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = ['name', 'email', 'password']; /** * The attributes excluded from the model's JSON form. * * @var array */ protected $hidden = ['password', 'remember_token']; // user has many posts public function posts() { return $this->hasMany('App\Posts','author_id'); } // user has many comments public function comments() { return $this->hasMany('App\Comments','from_user'); } public function can_post() { $role = $this->role; if($role == 'author' || $role == 'admin') { return true; } return false; } public function is_admin() { $role = $this->role; if($role == 'admin') { return true; } return false; } }
Part 3: Controllers
我們可用以下指令讓 Artisan 幫助我們自動產生 controllers:php artisan make:controller UserController php artisan make:controller PostController php artisan make:controller CommentController這些指令會在 app/Http/Controllers 產生 3 個檔案:UserController.php、PostController.php 及 CommentController.php
PostController
:<?php namespace App\Http\Controllers; use App\Posts; use App\User; use Redirect; use App\Http\Controllers\Controller; use App\Http\Requests\PostFormRequest; use Illuminate\Http\Request; class PostController extends Controller { // 顯示所有文章 public function index() { //fetch 5 posts from database which are active and latest $posts = Posts::where('active',1)->orderBy('created_at','desc')->paginate(5); //page heading $title = 'Latest Posts'; //return home.blade.php template from resources/views folder return view('home')->withPosts($posts)->withTitle($title); } // 建立新文章 public function create(Request $request) { // if user can post i.e. user is admin or author if($request->user()->can_post()) { return view('posts.create'); } else { return redirect('/')->withErrors('You have not sufficient permissions for writing post'); } } // 儲存文章 public function store(PostFormRequest $request) { $post = new Posts(); $post->title = $request->get('title'); $post->body = $request->get('body'); $post->slug = str_slug($post->title); $post->author_id = $request->user()->id; if($request->has('save')) { $post->active = 0; $message = 'Post saved successfully'; } else { $post->active = 1; $message = 'Post published successfully'; } $post->save(); return redirect('edit/'.$post->slug)->withMessage($message); } // 顯示一篇文章及它的留言 public function show($slug) { $post = Posts::where('slug',$slug)->first(); if(!$post) { return redirect('/')->withErrors('requested page not found'); } $comments = $post->comments; return view('posts.show')->withPost($post)->withComments($comments); } // 編輯文章 public function edit(Request $request,$slug) { $post = Posts::where('slug',$slug)->first(); if($post && ($request->user()->id == $post->author_id || $request->user()->is_admin())) return view('posts.edit')->with('post',$post); return redirect('/')->withErrors('you have not sufficient permissions'); } // 更新資料庫的文章 public function update(Request $request) { // $post_id = $request->input('post_id'); $post = Posts::find($post_id); if($post && ($post->author_id == $request->user()->id || $request->user()->is_admin())) { $title = $request->input('title'); $slug = str_slug($title); $duplicate = Posts::where('slug',$slug)->first(); if($duplicate) { if($duplicate->id != $post_id) { return redirect('edit/'.$post->slug)->withErrors('Title already exists.')->withInput(); } else { $post->slug = $slug; } } $post->title = $title; $post->body = $request->input('body'); if($request->has('save')) { $post->active = 0; $message = 'Post saved successfully'; $landing = 'edit/'.$post->slug; } else { $post->active = 1; $message = 'Post updated successfully'; $landing = $post->slug; } $post->save(); return redirect($landing)->withMessage($message); } else { return redirect('/')->withErrors('you have not sufficient permissions'); } } // 刪除文章 public function destroy(Request $request, $id) { // $post = Posts::find($id); if($post && ($post->author_id == $request->user()->id || $request->user()->is_admin())) { $post->delete(); $data['message'] = 'Post deleted Successfully'; } else { $data['errors'] = 'Invalid Operation. You have not sufficient permissions'; } return redirect('/')->with($data); }
CommentController:
<?php namespace App\Http\Controllers; use App\Posts; use App\Comments; use Redirect; use App\Http\Requests; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class CommentController extends Controller { public function store(Request $request) { //on_post, from_user, body $input['from_user'] = $request->user()->id; $input['on_post'] = $request->input('on_post'); $input['body'] = $request->input('body'); $slug = $request->input('slug'); Comments::create( $input ); return redirect($slug)->with('message', 'Comment published'); } }UserController 會稍後完成
Part 4: 前端網頁
之前主要完成了日誌的後端程式,現在會完成前端版面設計。把 resources/views/app.blade.php 改成
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Blog Demo | Find All Together</title> <link href="{{ asset('/css/app.css') }}" rel="stylesheet"> <!-- Fonts --> <link href='//fonts.googleapis.com/css?family=Roboto:400,300' rel='stylesheet' type='text/css'> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle Navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="http://www.findalltogether.com">Find All Together</a> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li> <a href="{{ url('/') }}">Home</a> </li> </ul> <ul class="nav navbar-nav navbar-right"> @if (Auth::guest()) <li> <a href="{{ url('/auth/login') }}">Login</a> </li> <li> <a href="{{ url('/auth/register') }}">Register</a> </li> @else <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ Auth::user()->name }} <span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> @if (Auth::user()->can_post()) <li> <a href="{{ url('/new-post') }}">Add new post</a> </li> <li> <a href="{{ url('/user/'.Auth::id().'/posts') }}">My Posts</a> </li> @endif <li> <a href="{{ url('/user/'.Auth::id()) }}">My Profile</a> </li> <li> <a href="{{ url('/auth/logout') }}">Logout</a> </li> </ul> </li> @endif </ul> </div> </div> </nav> <div class="container"> @if (Session::has('message')) <div class="flash alert-info"> <p class="panel-body"> {{ Session::get('message') }} </p> </div> @endif @if ($errors->any()) <div class='flash alert-danger'> <ul class="panel-body"> @foreach ( $errors->all() as $error ) <li> {{ $error }} </li> @endforeach </ul> </div> @endif <div class="row"> <div class="col-md-10 col-md-offset-1"> <div class="panel panel-default"> <div class="panel-heading"> <h2>@yield('title')</h2> @yield('title-meta') </div> <div class="panel-body"> @yield('content') </div> </div> </div> </div> <div class="row"> <div class="col-md-10 col-md-offset-1"> <p>Copyright © 2015 | <a href="http://www.findalltogether.com">Find All Together</a></p> </div> </div> </div> <!-- Scripts --> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script> </body> </html>
首頁版面 home.blade.php :
@extends('app') @section('title') {{$title}} @endsection @section('content') @if ( !$posts->count() ) There is no post till now. Login and write a new post now!!! @else <div class=""> @foreach( $posts as $post ) <div class="list-group"> <div class="list-group-item"> <h3><a href="{{ url('/'.$post->slug) }}">{{ $post->title }}</a> @if(!Auth::guest() && ($post->author_id == Auth::user()->id || Auth::user()->is_admin())) @if($post->active == '1') <button class="btn" style="float: right"><a href="{{ url('edit/'.$post->slug)}}">Edit Post</a></button> @else <button class="btn" style="float: right"><a href="{{ url('edit/'.$post->slug)}}">Edit Draft</a></button> @endif @endif </h3> <p>{{ $post->created_at->format('M d,Y \a\t h:i a') }} By <a href="{{ url('/user/'.$post->author_id)}}">{{ $post->author->name }}</a></p> </div> <div class="list-group-item"> <article> {!! str_limit($post->body, $limit = 1500, $end = '....... <a href='.url("/".$post->slug).'>Read More</a>') !!} </article> </div> </div> @endforeach {!! $posts->render() !!} </div> @endif @endsection在 resources/views 新增一個 posts 資料夾
在 resources/views/posts 建立一個新文件 create.blade.php
@extends('app') @section('title') Add New Post @endsection @section('content') <form action="/new-post" method="post"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <input required="required" value="{{ old('title') }}" placeholder="Enter title here" type="text" name = "title"class="form-control" /> </div> <div class="form-group"> <textarea name='body'class="form-control">{{ old('body') }}</textarea> </div> <input type="submit" name='publish' class="btn btn-success" value = "Publish"/> <input type="submit" name='save' class="btn btn-default" value = "Save Draft" /> </form> @endsection
在 resources/views/posts 建立另一個新文件 show.blade.php
@extends('app') @section('title') @if($post) {{ $post->title }} @if(!Auth::guest() && ($post->author_id == Auth::user()->id || Auth::user()->is_admin())) <button class="btn" style="float: right"><a href="{{ url('edit/'.$post->slug)}}">Edit Post</a></button> @endif @else Page does not exist @endif @endsection @section('title-meta') <p>{{ $post->created_at->format('M d,Y \a\t h:i a') }} By <a href="{{ url('/user/'.$post->author_id)}}">{{ $post->author->name }}</a></p> @endsection @section('content') @if($post) <div> {!! $post->body !!} </div> <div> <h2>Leave a comment</h2> </div> @if(Auth::guest()) <p>Login to Comment</p> @else <div class="panel-body"> <form method="post" action="/comment/add"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <input type="hidden" name="on_post" value="{{ $post->id }}"> <input type="hidden" name="slug" value="{{ $post->slug }}"> <div class="form-group"> <textarea required="required" placeholder="Enter comment here" name = "body" class="form-control"></textarea> </div> <input type="submit" name='post_comment' class="btn btn-success" value = "Post"/> </form> </div> @endif <div> @if($comments) <ul style="list-style: none; padding: 0"> @foreach($comments as $comment) <li class="panel-body"> <div class="list-group"> <div class="list-group-item"> <h3>{{ $comment->author->name }}</h3> <p>{{ $comment->created_at->format('M d,Y \a\t h:i a') }}</p> </div> <div class="list-group-item"> <p>{{ $comment->body }}</p> </div> </div> </li> @endforeach </ul> @endif </div> @else 404 error @endif @endsection
resources/views/posts/edit.blade.php
@extends('app') @section('title') Edit Post @endsection @section('content') <form method="post" action='{{ url("/update") }}'> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <input type="hidden" name="post_id" value="{{ $post->id }}{{ old('post_id') }}"> <div class="form-group"> <input required="required" placeholder="Enter title here" type="text" name = "title" class="form-control" value="@if(!old('title')){{$post->title}}@endif{{ old('title') }}"/> </div> <div class="form-group"> <textarea name='body'class="form-control"> @if(!old('body')) {!! $post->body !!} @endif {!! old('body') !!} </textarea> </div> @if($post->active == '1') <input type="submit" name='publish' class="btn btn-success" value = "Update"/> @else <input type="submit" name='publish' class="btn btn-success" value = "Publish"/> @endif <input type="submit" name='save' class="btn btn-default" value = "Save As Draft" /> <a href="{{ url('delete/'.$post->id.'?_token='.csrf_token()) }}" class="btn btn-danger">Delete</a> </form> @endsection
Part 5: 增添 tinyMCE 及 用戶個人檔案
這個系列最後一篇教學是在建立文章的版面嵌入 tinyMCE(所見即所得編輯器)及完成用戶個人檔案的前後端。增添 tinyMCE
到 http://www.tinymce.com/download/download.php 下載 tinyMCE 共解壓縮至 public/js 把 resources/views/posts/edit.blade.php 改成@extends('app') @section('title') Edit Post @endsection @section('content') <script type="text/javascript" src="{{ asset('/js/tinymce/tinymce.min.js') }}"></script> <script type="text/javascript"> tinymce.init({ selector : "textarea", plugins : ["advlist autolink lists link image charmap print preview anchor", "searchreplace visualblocks code fullscreen", "insertdatetime media table contextmenu paste"], toolbar : "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image" }); </script> <form method="post" action='{{ url("/update") }}'> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <input type="hidden" name="post_id" value="{{ $post->id }}{{ old('post_id') }}"> <div class="form-group"> <input required="required" placeholder="Enter title here" type="text" name = "title" class="form-control" value="@if(!old('title')){{$post->title}}@endif{{ old('title') }}"/> </div> <div class="form-group"> <textarea name='body'class="form-control"> @if(!old('body')) {!! $post->body !!} @endif {!! old('body') !!} </textarea> </div> @if($post->active == '1') <input type="submit" name='publish' class="btn btn-success" value = "Update"/> @else <input type="submit" name='publish' class="btn btn-success" value = "Publish"/> @endif <input type="submit" name='save' class="btn btn-default" value = "Save As Draft" /> <a href="{{ url('delete/'.$post->id.'?_token='.csrf_token()) }}" class="btn btn-danger">Delete</a> </form> @endsection同樣地,把 resources/views/posts/create.blade.php 改成
@extends('app') @section('title') Add New Post @endsection @section('content') <script type="text/javascript" src="{{ asset('/js/tinymce/tinymce.min.js') }}"></script> <script type="text/javascript"> tinymce.init({ selector : "textarea", plugins : ["advlist autolink lists link image charmap print preview anchor", "searchreplace visualblocks code fullscreen", "insertdatetime media table contextmenu paste"], toolbar : "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image" }); </script> <form action="/new-post" method="post"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <input required="required" value="{{ old('title') }}" placeholder="Enter title here" type="text" name = "title"class="form-control" /> </div> <div class="form-group"> <textarea name='body'class="form-control">{{ old('body') }}</textarea> </div> <input type="submit" name='publish' class="btn btn-success" value = "Publish"/> <input type="submit" name='save' class="btn btn-default" value = "Save Draft" /> </form> @endsection
用戶個人檔案
把 UserController.php 改成<?php namespace App\Http\Controllers; use App\Http\Requests; use App\Http\Controllers\Controller; use App\User; use App\Posts; use Illuminate\Http\Request; class UserController extends Controller { /* * Display active posts of a particular user * * @param int $id * @return view */ public function user_posts($id) { // $posts = Posts::where('author_id',$id)->where('active',1)->orderBy('created_at','desc')->paginate(5); $title = User::find($id)->name; return view('home')->withPosts($posts)->withTitle($title); } /* * Display all of the posts of a particular user * * @param Request $request * @return view */ public function user_posts_all(Request $request) { // $user = $request->user(); $posts = Posts::where('author_id',$user->id)->orderBy('created_at','desc')->paginate(5); $title = $user->name; return view('home')->withPosts($posts)->withTitle($title); } /* * Display draft posts of a currently active user * * @param Request $request * @return view */ public function user_posts_draft(Request $request) { // $user = $request->user(); $posts = Posts::where('author_id',$user->id)->where('active',0)->orderBy('created_at','desc')->paginate(5); $title = $user->name; return view('home')->withPosts($posts)->withTitle($title); } /** * profile for user */ public function profile(Request $request, $id) { $data['user'] = User::find($id); if (!$data['user']) return redirect('/'); if ($request -> user() && $data['user'] -> id == $request -> user() -> id) { $data['author'] = true; } else { $data['author'] = null; } $data['comments_count'] = $data['user'] -> comments -> count(); $data['posts_count'] = $data['user'] -> posts -> count(); $data['posts_active_count'] = $data['user'] -> posts -> where('active', '1') -> count(); $data['posts_draft_count'] = $data['posts_count'] - $data['posts_active_count']; $data['latest_posts'] = $data['user'] -> posts -> where('active', '1') -> take(5); $data['latest_comments'] = $data['user'] -> comments -> take(5); return view('admin.profile', $data); } }
前端版面:
在 resources/views 新增一個 admin 資料夾,然後在此資料夾新增一個 profile.blade.php 檔案@extends('app') @section('title') {{ $user->name }} @endsection @section('content') <div> <ul class="list-group"> <li class="list-group-item"> Joined on {{$user->created_at->format('M d,Y \a\t h:i a') }} </li> <li class="list-group-item panel-body"> <table class="table-padding"> <style> .table-padding td{ padding: 3px 8px; } </style> <tr> <td>Total Posts</td> <td> {{$posts_count}}</td> @if($author && $posts_count) <td><a href="{{ url('/my-all-posts')}}">Show All</a></td> @endif </tr> <tr> <td>Published Posts</td> <td>{{$posts_active_count}}</td> @if($posts_active_count) <td><a href="{{ url('/user/'.$user->id.'/posts')}}">Show All</a></td> @endif </tr> <tr> <td>Posts in Draft </td> <td>{{$posts_draft_count}}</td> @if($author && $posts_draft_count) <td><a href="{{ url('my-drafts')}}">Show All</a></td> @endif </tr> </table> </li> <li class="list-group-item"> Total Comments {{$comments_count}} </li> </ul> </div> <div class="panel panel-default"> <div class="panel-heading"><h3>Latest Posts</h3></div> <div class="panel-body"> @if(!empty($latest_posts[0])) @foreach($latest_posts as $latest_post) <p> <strong><a href="{{ url('/'.$latest_post->slug) }}">{{ $latest_post->title }}</a></strong> <span class="well-sm">On {{ $latest_post->created_at->format('M d,Y \a\t h:i a') }}</span> </p> @endforeach @else <p>You have not written any post till now.</p> @endif </div> </div> <div class="panel panel-default"> <div class="panel-heading"><h3>Latest Comments</h3></div> <div class="list-group"> @if(!empty($latest_comments[0])) @foreach($latest_comments as $latest_comment) <div class="list-group-item"> <p>{{ $latest_comment->body }}</p> <p>On {{ $latest_comment->created_at->format('M d,Y \a\t h:i a') }}</p> <p>On post <a href="{{ url('/'.$latest_comment->post->slug) }}">{{ $latest_comment->post->title }}</a></p> </div> @endforeach @else <div class="list-group-item"> <p>You have not commented till now. Your latest 5 comments will be displayed here</p> </div> @endif </div> </div> @endsection快速入門教學到此為止,完整文檔請到 Laravel 官方網站查看。
留言
張貼留言