1. View Separation and nesting
To run the command under the Learnlaravel folder:
PHP Artisan Generate:view Admin._layouts.default
At this time the generator plugin helped us create the app/views/admin/_layouts/default.blade.php file, modifying the content to:
<!doctype html>
<meta charset= "Utf-8" >
<title>learn Laravel 4</title>
@include (' Admin._partials.assets ')
<body>
<div class= "Container" >
<div class= "NavBar navbar-inverse navbar-fixed-top" >
<div class= "Navbar-inner" >
<div class= "Container" >
<a class= "brand" href= "{{url::route (' Admin.pages.index ')}}" >learn Laravel 4</a>
@include (' admin._partials.navigation ')
</div>
</div>
</div>
@yield (' main ')
</div>
</body>
This is the view file, V in MVC. The view needs to be carefully talked about.
The Views folder is a view folder, and the view folder can be nested, just like I did. created a admin/_layout nested folder, In which we created a file called default.blade.php, so that when we use this view anywhere in Laravel, he is called Admin._layouts.default.
We see that the seventh line of the code above is "@include (' admin._partials.assets ')", which, according to the knowledge we just learned above, means loading another file. The blade is the Laravel template engine, where the @include indicates that all the code for that file is brought in and put here, into a part of the current view.
Note that line 25th "@yield (' main ')", what does that mean? This is a bit complicated, we'll talk about it later.
2. Permission Verification
Laravel support standard HTTP authentication, but here we need to build a blog system, so we will write a perfect admin login system, login from the page.
Use the command line to create the app/views/admin/auth/login.blade.php file with the following code:
@extends (' Admin._layouts.default ')
@section (' main ')
<div id= "Login" class= "Login" >
{{Form::open ()}}
@if ($errors->has (' login '))
<div class= "alert Alert-error" >{{$errors->first (' Login ', ': Message ')}}</div>
@endif
<div class= "Control-group" >
{{Form::label (' email ', ' email ')}}
<div class= "Controls" >
{{form::text (' email ')}}
</div>
</div>
<div class= "Control-group" >
{{Form::label (' password ', ' Password ')}}
<div class= "Controls" >
{{Form::p assword (' Password ')}}
</div>
</div>
<div class= "Form-actions" >
{{form::submit (' Login ', Array (' class ' => ' btn btn-inverse btn-login ')}}
</div>
{{form::close ()}}
</div>
@stop
You should be aware of the first two lines:
@extends (' Admin._layouts.default ') @section (' main ')
What does that mean? In fact, we'll learn later that when we call view in controller, it's just the login.blade.php file, and the first line indicates that this view is Admin._ Layouts.default's child view, then the blade engine will load the view into it, how to assemble it? The next @section (' main ') should be out, and the code wrapped by it will be placed directly in the @yield (' main ') in Admin._layouts.default. Section and yield can be arbitrary, as long as two views have a call between the relationship, they can be used, very flexible.
There may be a question here, why are there so many empty lines in the sample code? This is a personal experience. All tags of the blade engine are treated with regular processing when the view is compiled. The engine itself has a problem, is not a bug, that is, the line break will be processed, causing the front and back lines and the line are tightly squeezed together, in the front-end browser "view source code", the more unclear, before and after the above can solve this problem. Of course this may be an automatic "compression" feature that is no longer discussed in depth.
Add controller file app/controllers/admin/authcontroller.php, this time someone said, this I know, haha, run
"PHP artisan generate:controller Admin. Authcontroller "
The idea is right, but do you want to run it for a try? Will create a "admin" directly under the App/controllers directory. authcontroller.php "file, someone said," Then I use the "Admin/authcontroller" row, you try? I can't do that. So let's start by manually creating the Admin folder under App/controllers, and then the command line to enter:
PHP Artisan Generate:controller Admin/authcontroller
That's it. The next rewrite of the authcontroller.php content is:
<?php
namespace App\controllers\admin;
Use Auth, Basecontroller, Form, Input, Redirect, Sentry, View;
Class Authcontroller extends Basecontroller {
/**
* Show Login Page
* @return View
*/
Public Function GetLogin ()
{
Return View::make (' Admin.auth.login ');
}
/**
* POST Login Verification
* @return Redirect
*/
Public Function Postlogin ()
{
$credentials = Array (
' Email ' => input::get (' email '),
' Password ' => input::get (' password ')
);
Try
{
$user = Sentry::authenticate ($credentials, false);
if ($user)
{
Return Redirect::route (' Admin.pages.index ');
}
}
catch (\exception $e)
{
Return Redirect::route (' Admin.login ')->witherrors (Array (' login ' => $e->getmessage ()));
}
}
/**
* Cancellation
* @return Redirect
*/
Public Function Getlogout ()
{
Sentry::logout ();
Return Redirect::route (' Admin.login ');
}
}
This is the controller we log in to, Logoff, C in MVC. Next I will explain the namespace, this is the foundation of the Laravel, or is the foundation of composer, is the whole laravel the focus of the tutorial, difficult points, I hope everyone penny, any do not understand do not let go. You can go to the Phphub Forum or Golaravel forum to ask the following questions, or directly post questions.
We first look at the location of this file, which is located in the App/controllers/admin directory, what's the difference? In other frameworks such as CI, subfolders can be called directly with folder names, although there is only one layer at most. And Laravel is not so simple, involved in the PHP namespace.
1. The composer supports the PSR-0 and PSR-4 standards, which stipulate that PHP packages are differentiated by namespaces and provide services outside, and that all exposed classes should be under the \ author name \ Package name namespace, such as the \lui\mffc\mail class. This way, even the name of the package as long as the different authors can coexist on the https://packagist.org/, for everyone to use.
2. Namespaces can be likened to a directory in a Linux system, where all files and executables under the current directory can be opened directly using file names in any directory, and absolute or relative paths are required if you need to open files in other directories.
3. In many other tutorials, you may have seen controller head without a NAMESAPCE statement, not even a bunch of use XXX, like this file https://github.com/cecoo/laravel4demo/blob/ master/app/controllers/blogcontroller.php. This file in line 8th directly using the Blog this class, this is why?
Since they have all been declared as automatic loading in the learnlaravel of this composer application, they are automatically added as top-level namespaces without declaring their namespaces at the top. This configuration file is Composer.json, and the object configuration item is a CLASSMAP item under AutoLoad. This declaration will allow Composer to automatically scan all classes in the file and all of the subfolders as soon as the file is generated, and will automatically be loaded as a top-level space without declaring a particular namespace. "Wrong statement before, hereby correct!" 】
For more information about namespaces, refer to "Getting started with the PHP namespace."
OK, so far our MVC ternary has been set up, so what should we do next? Configure routing. The route here is not the home with no line by the:-D, but the user requested URL to the controller a method of conversion, function is the smallest unit of code in PHP, so the user requested a path, such as Http://ooxx.com/fuck/me, After this URL is routed, the route resolves, which function should be called, and the result is returned to the user.
Laravel routes return results in a closed package, adding the following in app/routes.php:
Route::get (' Admin/logout ', Array (' as ' => ' admin.logout ', ' uses ' => ') app\controllers\admin\ Authcontroller@getlogout '));
Route::get (' Admin/login ', Array (' as ' => ' admin.login ', ' uses ' => ') app\controllers\admin\ Authcontroller@getlogin '));
Route::p ost (' Admin/login ', Array (' as ' => ' admin.login.post ', ' uses ' => ') app\controllers\admin\ Authcontroller@postlogin '));
Route::group (Array (' prefix ' => ' admin ', ' before ' => ' auth.admin '), function ()
{
Route::any ('/', ' app\controllers\admin\pagescontroller@index ');
Route::resource (' articles ', ' App\controllers\admin\articlescontroller ');
Route::resource (' pages ', ' App\controllers\admin\pagescontroller ');
});
The first three means hold to live two get requests and a POST request, the following is a routing group, which provides a prefix admin, adds a filter, auth.admin, a '/' path that can accommodate both getting and post requests, and its full path is http:/ /ooxx.com/admin/. The remaining two resource controllers are essentially shorthand, and the corresponding table of method names in the URL and controller class is shown in the resource controller.
The filter, Auth.admin, is a request filter provided by Laravel, which is next to the routing file, app/filters.php, added at the end of the file:
Route::filter (' Auth.admin ', function ()
{
if (! Sentry::check ()) {
Return Redirect::route (' Admin.login ');
}
});
So our permission verification is complete. The code above means that before entering any of the routes in this routing group, the filter will be passed through the auth.admin, which invokes Sentry::check () and, if False, enters the if code block, which jumps the user's request to the Named Route ' Admin.login ', named routing document. From the name of this named route you can also see, is to tell the visitors: stupid, what to do, login to ~
The "named routing" feature here is designed to mimic the routing bindings of Ruby on Rails's "link_to" to the object, but the PHP upload, which is the feature of the rogue process, makes it impossible to maintain a full code routing table that is not implemented like Rails. Resource routing-resource object-routing calls the three binding function, can only make a semi-finished product named route, artificially solves when adjusts/people to/human, the request name changes but the function is invariable, simultaneously requests the code to adapt the demand.
At this point, we can try to visit our project. Recommended configuration Apache points a port to Learnlaravel, the public directory of this project, where items are accessed through addresses such as http://127.0.0.1:8080, and are highly recommended for access from subfolders. If you don't, you can run
PHP Artisan Serve
Start PHP5.4 's built-in HTTP server. The address will be http://localhost:8000, note that 127.0.0.1 cannot be accessed here.
Below, we access/admin in the browser, note that the URL will automatically jump to/admin/login, which means that our filter works, but you may get the following page
This indicates that the code is wrong. Next we modify app/config/app.php the first item is:
' Debug ' => true,
Refresh the page, the error prompted out! There is no feeling Laravel4.2 the wrong hint is very good-looking ah, really good, but I do not think 4.1 before the good-looking:-D. I got the following error:
Say "App\controllers\admin\authcontroller" This class is not found, this is why? This document clearly has AH.
This involves another problem, the autoload problem in the laravel. Laravel is based on namespaces, it only automatically loads classes for all top-level namespaces, which means that our new controller class is not under the top-level namespace, so you need to tell Laravel that my class exists, how do I tell it? Run
Composer Dump-autoload
OK, refresh the page, he told me
View [admin._partials.assets] not found.
This is true, we haven't established this document yet. Set up an empty file, if it is built with generator, don't forget to delete the contents of the default inside OH. Refresh the page again, if there is a problem, I believe you can solve the problem yourself.
OK, an ugly force of the page appears, why is it so ugly? (Why are pigeons so big?) Because we did not introduce any CSS and JS files, even the navigation bar of the HTML is not complete. This does not matter, come, according to my GitHub on the code, copy yourself to the corresponding file. In addition, it is very important to copy the JS and CSS two folders under the public files in my project to your public folder completely.
Refresh again, if you see the following page, you are successful!
3. Try to Login
Add an administrator with seed and add an administrator group. New app/database/seeds/sentryseeder.php, content is:
<?php
Class Sentryseeder extends Seeder {
Public Function Run ()
{
Db::table (' users ')->delete ();
Db::table (' groups ')->delete ();
Db::table (' users_groups ')->delete ();
Sentry::getuserprovider ()->create (Array (
' Email ' => ' oo@xx.com ',
' Password ' => ' Ooxx ',
' First_Name ' => ' OO ',
' Last_Name ' => ' XX ',
' Activated ' => 1,
));
Sentry::getgroupprovider ()->create (Array (
' Name ' => ' Admin ',
' Permissions ' => [' admin ' => 1],
));
To add a user to a user group
$adminUser = Sentry::getuserprovider ()->findbylogin (' oo@xx.com ');
$adminGroup = Sentry::getgroupprovider ()->findbyname (' Admin ');
$adminUser->addgroup ($adminGroup);
}
}
Add a new line to app/database/seeds/databaseseeder.php:
$this->call (' Sentryseeder ');
And then run:
PHP Artisan Db:seed
After the success of the database, you will find that users, groups, users_groups tables have a new line. However, articles and the pages table also added 10 lines respectively, yes, seed is so stupid Meng ^_^
Let's try to login! If you get:
Class App\controllers\admin\pagescontroller does not exist
It means you've succeeded!