此文章爲原創文章,未經贊成,禁止轉載。php
laravel 5.2 以後請使用 laravelcollective/html 替換 illuminate/html. 出現問題先看評論。css
在開始以前,咱們把界面先美化一點點先:html
首先到https://github.com/JellyBool/blog-css-js獲得靜態文件,而後分別修改下面三個文件:laravel
1. app.blade.php 2. articles/index.blade.php 3. articles/show.blade.php
下面的視圖代碼的修改部分,若是你偷懶,你可使用ctrl+c
大法。git
在app.blade.php
中:將原來@yield('content')
的代碼替換成下面的代碼:github
<body>
<div class="container"> <section class="content"> <div class="pad group"> @yield('content') </div> </section> </div> </body>
就是在外面多加了個div和一個section。web
再引入這兩個css文件:數據庫
<link rel='stylesheet' href="/css/bootstrap.min.css" type='text/css' media='all'/> <link rel='stylesheet' href="/css/all.css" type='text/css' media='all'/>
一個是bootstrap,一個是自定義的。bootstrap
在articles/index.blade.php
文件中,咱們將每一個$article
放在<article>
標籤中:segmentfault
@foreach($articles as $article)
<article class="format-image group"> <h2 class="post-title pad"> <a href="/articles/{{ $article->id }}"> {{ $article->title }}</a> </h2> <div class="post-inner"> <div class="post-deco"> <div class="hex hex-small"> <div class="hex-inner"><i class="fa"></i></div> <div class="corner-1"></div> <div class="corner-2"></div> </div> </div> <div class="post-content pad"> <div class="entry custome"> {{ $article->intro }} </div> <a class="more-link-custom" href="/articles/{{ $article->id }}"><span><i>更多</i></span></a> </div> </div> </article> @endforeach
而後最後就是修改articles/show.blade.php
視圖文件了:
@section('content')
<article class="format-image group"> <h2 class="post-title pad"> <a href="/articles/{{ $article->id }}" rel="bookmark"> {{ $article->title }}</a> </h2> <div class="post-inner"> <div class="post-content pad"> <div class="entry custome"> {{ $article->content }} </div> </div> </div> </article> @endsection
最後看看效果:
教程的最後,基本上就能夠完成一個跟本人的blog同樣的小產品。
OK,稍微美化完事後,咱們就能夠進入咱們的主題了:在Laravel中使用Forms表單。
既然咱們須要建立一篇文章,咱們首先仍是須要將這個建立文章的頁面展現出來吧,就像SF的文章撰寫頁面同樣:http://segmentfault.com/write
因此咱們須要將上一篇的內容走一遍:
註冊路由,在routes.php
中增長:
Route::get('article/create','ArticleController@create');
咱們指定article/create
來加載ArticleController
的create()
方法,而後咱們在ArticleController
建立之:
public function create() { return view('articles.create'); }
這個create()方法直接加載咱們的create.blade.php
,因此咱們建立這個視圖文件,來到以前的views/articles/這個文件夾中,新建create.blade.php
,寫上這些測試內容:
@extends('app') @section('content') <h1>撰寫新文章</h1> @endsection
瀏覽器訪問試試http://blog.dev/article/create:
一切正確加載以後,咱們就開始着手咱們的Forms使用了,由於建立文章的時候就是須要表單的提交,咱們才能夠將內容接收到,或者說幾乎每個web應用都離不開表單,哪怕是一個註冊,登陸頁面,也都是須要表單的存在,只要你須要收集用戶的信息或者但願有一些UGC,也離不開表單。因此咱們開始使用Laravel的Forms表單吧。
這裏咱們使用一個官方的Package:https://github.com/illuminate/html
咱們經過composer來安裝之:
composer require illuminate/html
靜待一會,安裝成功以後,咱們們怎麼告訴Laravel,這個Package已經安裝了?或者說咱們怎麼將這個Package跟Laravel的整個體系結合起來呢?
經過提供Service Provider和指定Facade!這樣就能夠很完美地與Laravel結合了。
爲何直接叫Service Provider和Facade?由於我知道怎麼翻譯這兩個才貼切,意會一下
在這裏順便多說一點:在PHP的不少composer的package中,都會有各個框架的不一樣版本,好比說HtmlPurifier這個過濾html和預防xss的package,就有這個Laravel的版本:https://github.com/mewebstudio/Purifier ,或多或少,一些很好的package都會有Laravel的版本。
那麼說回Service Provider和Facade,剛開始可能對Service Provider的概念可能很迷惑,不過你如今徹底沒必要要擔憂,儘管打開config/app.php
這個文件看一看:
'providers' => [ Illuminate\Foundation\Providers\ArtisanServiceProvider::class, Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, //... ]
你會看到providers
這個數組裏面會有一堆Laravel預置的Service Provider,好比咱們常用到得Auth,Controller等,均可以在這裏找到。若是你再往下拉,你還會看到一個這樣的aliases
數組:
'aliases' => [ 'App' => Illuminate\Support\Facades\App::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Auth' => Illuminate\Support\Facades\Auth::class, //... ]
aliases其實就是快捷方式了,一旦在這裏指定了快捷方式,咱們就能夠在Laravel中全局使用,好比我在代碼中使用Auth
,其實背後我就是在用Illuminate\Support\Facades\Auth::class
,而後再深刻,咱們實際上是在用providers
中的Illuminate\Auth\AuthServiceProvider::class
這個。
趁上面寫這些的時候illuminate/html
已經下載好了:
那麼,按照上面方式,咱們來配置一下咱們的illuminate/html
,在config/app.php
中的providers添加咱們的Service Provider:
Illuminate\Html\HtmlServiceProvider::class,
配置完大概長這樣:
OK,Service Provider添加好了以後,咱們來添加咱們的Facade,也就是在aliases
這個數值後面添加:
'Form' => Illuminate\Html\FormFacade::class,
配置完以後看看圖片長這樣:
這兩個配置好了以後,咱們就能夠在在咱們的create.blade.php
這個視圖中使用它了:
@section('content') <h1>撰寫新文章</h1> {!! Form::open() !!} {!! Form::close() !!} @endsection
咱們加入了兩行{!! Form::open() !!}
和{!! Form::close() !!}
,至於{!!
相似的符號,請類好比blade的{{
,不用太糾結這個。咱們再來訪問http://blog.dev/article/create試試:
咋一看,貌似沒有什麼變化,可是你要查看頁面源碼或者使用開發者工具檢查元素的時候,就能夠發現這個form元素已經建立出來了。
不難發現,Laravel的Form還默認爲咱們生成一個hidden的表單(name="_token"),這個是Laravel默認對錶單提交的一點安全支持。在表單提交的時候,Laravel會自動檢查這個_token
是否與保存在session中的_token
一致,若是不一致,那就直接跳轉回遠頁面,不容許咱們提交數據。
既然Form能夠正常使用了,咱們就能夠建立咱們須要的表單了:
{!! Form::open() !!}
<div class="form-group"> {!! Form::label('title','標題:') !!} {!! Form::text('title',null,['class'=>'form-control']) !!} </div> <div class="form-group"> {!! Form::label('content','正文:') !!} {!! Form::textarea('content',null,['class'=>'form-control']) !!} </div> <div class="form-group"> {!! Form::submit('發表文章',['class'=>'btn btn-success form-control']) !!} </div> {!! Form::close() !!}
咱們在{!! Form::open() !!}
加入一點東西,先來看看咱們的效果:
下面詳細解釋一下:
{!! Form::text('title',null,['class'=>'form-control']) !!}
拿這個來開刀吧:
Form::text
表示<input type='text' />
,還要一堆好比 <input type='password' />
等你能夠參照着寫。
'title'
表示 name='title'
null
表示 value=''
'class'=>'form-control'
表示class='form-control'
,這裏能夠指定id
,placeholder
等一系列你想指定的屬性
然而在Form::open()
沒有指定提交路徑的狀況之下,默認是提交到本頁面,這樣對於咱們的清晰分工是不太好的,由於這個頁面就是用來加載視圖的,而對於咱們表單提交的內容,咱們但願用另外的方法來處理,因此咱們來寫一寫吧。
首先在Form::open()
指定表單提交的url,直接在加入url:
{!! Form::open(['url'=>'article/store']) !!}
咱們指定表單post提交到article/store
這個地址,而後在routes.php
註冊這個路由地址:
Route::post('article/store','ArticleController@store');
這裏注意咱們使用了Route::post
而不是Route::get
,這是用來接收post的路由。而後順利成章,在ArticleController
中建立store()
方法:
public function store() { $input = Request::all(); return $input; }
在這個方法中,咱們引入Laravel自帶的Request
並使用Request::all()
,來獲取全部的用戶提交的過來的內容(這裏指的是:_token
,name
很content
),若是你想獲取具體某一個表單輸入的內容,可使用Request::get()
,好比Request::get('title')
,而後直接return來看看用戶到底輸入了什麼內容,咱們來試試:
OK,成功拿到用戶的提交的內容以後,咱們須要將這些保存到數據庫,怎麼實現呢?在第四篇中,咱們提到的Eloquent
的create()
方法如今就能夠派上用場了,因而咱們能夠寫成這樣:
Article::create($input);
Laravel會自動過濾_token
這個提交內容。
可是建立完一篇文章以後,咱們並非想return $input
,而是想從新跳轉到某個頁面中,好比咱們的首頁,由於發表完文章,咱們須要看到它是否成功出線在文章列表中,因此咱們最後寫一下:
public function store() { $input = Request::all(); Article::create($input); return redirect('/'); }
咱們直接使用Laravel的redirect()
函數進行跳轉,跳轉到首頁。這個時候,短短的三行代碼就能夠將咱們的邏輯實現了,那麼咱們來試試:
貌似成功了?可是咱們以爲這個排序有點問題,最新建立的文章固然是在最上面的了,因此咱們到ArticleController
的index()
方法中稍微修改一下:
public function index() { $articles = Article::latest()->get(); return view('articles.index',compact('articles')); }
將原來的all()
換成了latest()->get()
,刷新,
咱們發現,最新的文章intro
居然空白,咱們到數據庫看看:
咱們發現,剛剛建立的文章的intro
爲空值,而published_at
爲0000-00-00 00:00:00
,這不是咱們想要的,爲何會這樣呢?由於咱們在提交過來的時候,並無這兩個數據啊,爲了解決這個問題,首先咱們能夠很暴力得將這兩個數據在使用Article::create($input)
以前配置好,好比:
public function store() { $input = Request::all(); //下面增長兩行,順便看看Request::get的使用 $input['intro'] = mb_substr(Request::get('content'),0,64); $input['published_at'] = Carbon::now(); Article::create($input); return redirect('/'); }
intro字段就直接取content字段的頭64個,而後published_at就默認爲建立的時間。目前開起來代碼有點暴力,可是不失爲一種解決方案,咱們後續會使代碼much cleaner。咱們再來試試:
bang,成功了,咱們在看看數據庫:
到這裏,咱們建立一篇文章的基本流程就完成了,可是這裏還有一個問題,若是你嘗試在文章建立的頁面什麼都不填,直接提交數據,你看看會發生什麼,若是不肯定,你能夠看看你的數據庫,到底發生了什麼。
##下一節
鑑於最後的問題和牽涉到表單的內容,下一節貌似很瓜熟蒂落就應該說說表單驗證了,在Laravel中就是Request Validation。
最後,
Happy Hacking