Вы находитесь на странице: 1из 11

The Blog that we will be creating has the following features :

twitter bootstrap layout implemented by bootstrapper bundle


user log in and authentification
display all posts in paginated view
create new posts
delete posts

Building with Laravel is very easy. When you know the basics, it will take only 10-15 minutes to build a blog like this
from scratch!

First, when creating even such a simple application as a three page blog, it is important to have an idea
and a plan before even starting to write any code. There are a lot of questions that need to be tackled
before coding, such as : how the application will look, which actions can it take and which data it will
operate with, what are good practices out there for this kind of application, etc.
Before I sat down to write any code for the blog application, I first sketched things on paper this is called
wireframing. Wireframing is very helpful when you are designing an application. It gives a visual idea of
how to position things on each page, and what elements will be used on each page forms, labels,
buttons, etc. I provide you with an example sketch I did on a Sticky and the one I would refer to while I
was building the blog application.
I drew three views of the blog the index page with all posts, the login page and the page where the user
would create new posts. I drew the views having in mind CSS/HTML framework that I use for quick
applications Twitter Bootstrap (http://twitter.github.com/bootstrap/), it makes great use of the grid-based
layout and speeds up development.
This was an extremely helpful first step because when I build a layout and views for my application I
already know where things should go and how they will be placed. I encourage you to sketch your web
apps before you get to coding them. Sometimes going through many iterations on paper can bring clarity
to your project.
When the sketches were done, I needed to think what data will my application use and how that data is
related to other data in the application, which brings us to the next part of the tutorial where we will learn
how to derive a data model and plan our database as a part of building a blog.

A little side topic : If you havent had much experience with Databases, dont worry, I will guide you
through the process for right now. But I do highly encourage you to take a database design class or at
least become a database design freak by talking a walk around where you liv, looking at objects thinking
that they are entities, taking them apart in your mind. For example look at the street, what does it have?
Houses, roads, cars, people, light poles, etc. Break down every object even further : House consists of
windows, walls, doors, roof, paint, etc. Cars consist of shell, wheels, glass, engine, seats, dashboard,
lights, exhaust, transmission, etc. Im not going to tell you which body parts humans consist of, you know
that yourself. This simple exercise makes you into a better database designer, when building an
application you will have to break data up into smaller pieces to make it usable.
Lets do that with our blog application. First ask questions, What kind of data are we operating with? What
attributes does the data have? How is the data interconnected? Think about that for a minute, please.
In a blog there is an author, lets call him/her a user. The user publishes posts, right? So that means we
have two kinds of data that should be somehow related: users and posts. Now lets break down each kind
further : which attributes do these kinds of data have? In most cases every kind of data has id by default,
then users have these attributes: username and password for logging in the system, some kind of name
or alias to be displayed (who published the post?), and timestamps information about when the user
was created or when the user was updated (in case we want to see history of our applications growth).
Lets do the same with Posts, every post has an id, some kind of title, the body of the post (text) and
some kind of way of telling by which author the post was published, lets have that as an integer that is
taken from Users id, and timestamps that tell us when the post was published and updated.
So that structure of our data brings us to the following database design, two tables named Posts and
Users with the attributes I described above. Heres the visual representation of the blog tables:

Now using the knowledge that we have learned in part 3 of the tutorial we need to build models to relate
the database tables to each other.
In Laravel models reside in your application/models folder and for clearer code I suggest you separate
your models into files corresponding to your database tables. For our blog application we have created
two tables by running our migrations,Posts and Users so now we just need to create two models, User
and Post (please note singular, not plural),
create two empty files in your application/models folder:
user.php
post.php
put [sourcecode]<?php[/sourcecode] as the first line in of each of those files (you dont have to close the
php tag)
In our application the posts belong to a user and a user has many posts. Following Laravels
documentation on Eloquent, we see that for each model we need to create a class with the same name
as the database table, so lets create the model that will go inside of user.php :
[sourcecode language="php"]
class User extends Eloquent {
}
[/sourcecode]
now we need to specify the relationship of the user to the posts model, insert this inside the User class :
[sourcecode language="php"]
public function posts()
{
return $this->has_many(Post);
}
[/sourcecode]
Thats it! Save and close the file user.php, here is the complete source of user.php inside models
folder :
[sourcecode language="php"]
<?php
// application/models/user.php
// The model for Users.
// A user has many posts.
class User extends Eloquent {
public function posts()
{
return $this->has_many(Post);
}
}
[/sourcecode]
We are done with the User model, simple, right?! Now lets create our Post model :
The posts belong to a user. Following Laravels documentation on Eloquent, we create the model that will
go inside of post.php :
[sourcecode language="php"]
class Post extends Eloquent {
}
[/sourcecode]
now we need to specify the relationship of the post to the user model, insert this inside the Post class :
[sourcecode language="php"]
public function user()
{
return $this->belongs_to(User,'post_author);
}
[/sourcecode]
A little sidenote, Laravel is so smart, if we had a column user_id in our posts table, we wouldnt even
have to specify that post_author is the foreign key in the posts table. See more about Laravels Eloquent
relationsips here: http://laravel.com/docs/database/eloquent#relationships
Save and close the file post.php, here is the complete source of post.php inside models folder :
[sourcecode language="php"]
<?php
// application/model/post.php
// The model for blog posts.
// the post belongs to a user and that relationship is identified by post_author in the Posts table
class Post extends Eloquent {
public function user()
{
return $this->belongs_to(User,'post_author);
}
}
[/sourcecode]
Thats it with the models, we have our Post and User models, relating the posts to the users, specifying
that a user has many posts and each post belongs to a user. This is so easy!
Now onto the routes for our blog application!
I want to mention that all applications in Laravel could use Routes and Controllers in conjunction to make
things happen (read: actions executed) but for this simple application using just routes will suffice.
Routes in Laravel can be valid for any HTTP verb (GET, POST, PUT, and DELETE), and in Laravel
routes are very expressive, for example if you want to show a page (not to process a submitted form), you
would use Route::get(name_of_the_route), if you want to process a submitted form you would use
Route::post(name_of_the_route), etc. Read more about Routing on http://laravel.com/docs/routing#the-
basics
In Laravel routes reside in application/routes.php file. Thats where we will put the code for all of our
actions that the blog application will take. When thinking about which routes to create, we need to define
how the application will function. In case of a simple blog, we need to :
have index page with all blog posts listed. If the user seeing the index page is an admin we show a Delete
Button under each post to be able to erase posts (user can only delete own posts, not someone elses.)
have a login page (show the login page with a form and act upon form submission)
have a page to create new blog posts (show the page with a form having two fields for blog post title and body,
and examine the form submittal)
have a way to logout from admin interface.
Having that as a reference, lets create a basic structure for our routes, this will be our skeleton for the
routes :
[sourcecode language="php"]
// show index page
Route::get(/, function() {
});
// When a user is logged in he/she is taken to creating new post
Route::get(admin, array(before => auth, do => function() {
}));
Route::delete(post/(:num), array(before => auth, do => function($id){
})) ;
// When the new post is submitted we handle that here
Route::post(admin, array(before => auth, do => function() {
}));
// Present the user with login form
Route::get(login, function() {
});
// Process the login form
Route::post(login, function() {
});
// Process Logout process
Route::get(logout, function() {
});
[/sourcecode]
Now, lets populate each of our routes with some meaningful actions.
We will be using Eloquent to retrieve data from our models and Blade templating engine to bind data to
views. Also we will use Laravels built in Pagination to break the data up and show only 5 blog entries per
page.
We need to retrieve all the posts of all users, order those posts from newest to oldest (descending) and
use the paginate function to have only 5 entries per page. Then we bind the retrieved posts to the home
view and display them.
Lets insert the following code into our
Route::get(/, function() { that will do just that:
[sourcecode language="php"]
$posts = Post::with(user)->order_by(updated_at, desc)->paginate(5);
return View::make(home)
->with(posts, $posts);
[/sourcecode]
Ok, great, now we have our index page route set up, lets create a route where the user can log in:
The route will just show us a login page (a form with two fields: username and password),
Insert the following one line of code into
Route::get(login, function() {
[sourcecode language="php"]
return View::make(login);
[/sourcecode]
We can show the page but now we need to process it when the user submits the form from the login
page. We will be using Laravels Auth class to attempt users authentication. Lets process the form, if the
user provides valid credentials, login and redirect to create new blog post page, otherwise show errors.
Insert this code into
Route::post(login, function() {
[sourcecode language="php"]
$userinfo = array(
username => Input::get(username),
password => Input::get(password)
);
if ( Auth::attempt($userinfo) )
{
return Redirect::to(admin);
}
else
{
return Redirect::to(login)
->with(login_errors, true);
}
[/sourcecode]
Great, now the user will be able to login and be redirected to the page to create new blog posts. If we
wanted the user to go to the home page after logging in, we would just replace the Redirect::to(login)
with Redirect::to(/). Simple, isnt it?
This will be our logout route, using Auth::logout() to log the user out and redirect to the home page:
[sourcecode language="php"]
// Process Logout process
Route::get(logout, function() {
Auth::logout();
return Redirect::to(/);
});
[/sourcecode]
Our application will check if the user is logged in and will present a new post view binding the users
data to our view (we will have a hidden field in that view that will identify the users blog entry).
Insert the following code into Route::get(admin, array(before => auth, do => function() {
[sourcecode language="php"]
$user = Auth::user();
return View::make(new)->with(user, $user);
[/sourcecode]
Great, we can see the home page, login, logout and see the create new post page!
All thats left to do is create a route to process new post submission and a route that deletes posts for the
logged in user.
These two routes need some more explanation.
When the post is submitted, we need to get the input from each field of the form. Then we will use
excellentLaravels Validation mechanism to let the user know if the title or the post body is empty and is
longer than a few characters. If validation fails (the post is empty or too short) we will redirect the user to
the same page displaying errors in the validation. Otherwise if all is ok, we will save the new post in the
database and redirect the user to the index page showing all posts.
[sourcecode language="php"]
Route::post(admin, array(before => auth, do => function() {
$new_post = array(
post_title => Input::get(post_title),
post_body => Input::get(post_body),
post_author => Input::get(post_author)
);
$rules = array(
post_title => required|min:3|max:255,
post_body => required|min:10
);
$validation = Validator::make($new_post, $rules);
if ( $validation -> fails() )
{
return Redirect::to(admin)
->with(user, Auth::user())
->with_errors($validation)
->with_input();
}
// create the new post after passing validation
$post = new Post($new_post);
$post->save();
// redirect to viewing all posts
return Redirect::to(/);
}));
[/sourcecode]
I was thinking of a simple way to manage the created posts and one way we could delete the existing
posts from the administrators view is to submit a DELETE verb from a form, binding the id of the blog
post under the currently logged in user.
I came up with the following code:
[sourcecode language="php"]
Route::delete(post/(:num), array(before => auth, do => function($id){
$delete_post = Post::with(user)->find($id);
$delete_post -> delete();
return Redirect::to(/)
->with(success_message, true);
})) ;
[/sourcecode]
That is all there is to our routes for the blog application.
As a learning challenge I recommend you transform this application from routes-only to routes and
controllers. Can you do it?
Here is the complete source code of the routes.php file :
[sourcecode language="php"]
<?php
// Index page is a list of all posts
Route::get(/, function() {
$posts = Post::with(user)->order_by(updated_at, desc)->paginate(5);
return View::make(home)
->with(posts, $posts);
});
// When a user is logged in he/she is taken to creating new post
Route::get(admin, array(before => auth, do => function() {
$user = Auth::user();
return View::make(new)->with(user, $user);
}));
Route::delete(post/(:num), array(before => auth, do => function($id){
$delete_post = Post::with(user)->find($id);
$delete_post -> delete();
return Redirect::to(/)
->with(success_message, true);
})) ;
// When the new post is submitted we handle that here
Route::post(admin, array(before => auth, do => function() {
$new_post = array(
post_title => Input::get(post_title),
post_body => Input::get(post_body),
post_author => Input::get(post_author)
);
$rules = array(
post_title => required|min:3|max:255,
post_body => required|min:10
);
$validation = Validator::make($new_post, $rules);
if ( $validation -> fails() )
{
return Redirect::to(admin)
->with(user, Auth::user())
->with_errors($validation)
->with_input();
}
// create the new post after passing validation
$post = new Post($new_post);
$post->save();
// redirect to viewing all posts
return Redirect::to(/);
}));
// Present the user with login form
Route::get(login, function() {
return View::make(login);
});
// Process the login form
Route::post(login, function() {
$userinfo = array(
username => Input::get(username),
password => Input::get(password)
);
if ( Auth::attempt($userinfo) )
{
return Redirect::to(admin);
}
else
{
return Redirect::to(login)
->with(login_errors, true);
}
});
// Process Logout process
Route::get(logout, function() {
Auth::logout();
return Redirect::to(/);
});
/*
|
| Application 404 & 500 Error Handlers
|
|
| To centralize and simplify 404 handling, Laravel uses an awesome event
| system to retrieve the response. Feel free to modify this function to
| your tastes and the needs of your application.
|
| Similarly, we use an event to handle the display of 500 level errors
| within the application. These errors are fired when there is an
| uncaught exception thrown in the application.
|
*/
Event::listen(404, function()
{
return Response::error(404);
});
Event::listen(500, function()
{
return Response::error(500);
});
/*
|
| Route Filters
|
|
| Filters provide a convenient method for attaching functionality to your
| routes. The built-in before and after filters are called before and
| after every request to your application, and you may even create
| other filters that can be attached to individual routes.
|
| Lets walk through an example
|
| First, define a filter:
|
| Route::filter(filter, function()
| {
| return Filtered!;
| });
|
| Next, attach the filter to a route:
|
| Router::register(GET /, array(before => filter, function()
| {
| return Hello World!;
| }));
|
*/
Route::filter(before, function()
{
// Do stuff before every request to your application
});
Route::filter(after, function($response)
{
// Do stuff after every request to your application
});
Route::filter(csrf, function()
{
if (Request::forged()) return Response::error(500);
});
Route::filter(auth, function()
{
if (Auth::guest()) return Redirect::to(login);
});
[/sourcecode]

Вам также может понравиться