on Tutorials

Laravel 4 tutorial – validation and front end – part 3

69 comments
Getting started with Laravel
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedInShare on RedditShare on StumbleUpon

This is the 3rd part of the Laravel 4 tutorial series, and the source code will be available on Github, under the 0.3.0 tag.

Also check out the rest of the Laravel 4 series here:

Laravel 4 Validation

In the previous part we added some CRUD actions to our backend, and we’re now able to manage our pages and articles. This is all good, but one crucial thing is missing. Validation.

I really like the idea of services in apps, and I’ve been using this kind of separation for a while now, so it seems like the best idea to use a validation service for our models.

Some people like to do the validation inside the model, some do it in controller, but in my opinion it is better to take it out into a service. Jeffrey Way from Nettuts did a nice screencast on validation, and you will find it is very similar to his way, since I’ve been doing it almost the same in some of my previous apps.

So let’s dive right in. So the idea is to create a validator class for each form. The validation rules will be defined inside this validator class. Since we have 2 types of content, we’ll need 2 validator classes, and an additional one as an abstract class that will contain the validation logic.

So let’s create a directory app/services/validators, and put the app/services directory inside ourcomposer.json so that the classes will be autoloaded:

"autoload": {
    "classmap": [
        "app/services"
    ]
}

Next we’ll create the abstract validator class:

app/services/validators/Validator.php

<?php namespace App\Services\Validators;

abstract class Validator {

    protected $data;

    public $errors;

    public static $rules;

    public function __construct($data = null)
    {
        $this->data = $data ?: \Input::all();
    }

    public function passes()
    {
        $validation = \Validator::make($this->data, static::$rules);

        if ($validation->passes()) return true;

        $this->errors = $validation->messages();

        return false;
    }

}

The $data variable will contain the input data that will be validated, the $errors variable will contain the errors of course and the $rules variable will contain the validation rules, and those rules will be defined in the actual content validator classes that will extend this class.

Before I explain the methods, let’s create our content validator classes with the rules:

app/service/validators/ArticleValidator.php

<?php namespace App\Services\Validators;

class ArticleValidator extends Validator {

    public static $rules = array(
        'title' => 'required',
        'body'  => 'required',
    );

}

app/service/validators/PageValidator.php

<?php namespace App\Services\Validators;

class PageValidator extends Validator {

    public static $rules = array(
        'title' => 'required',
        'body'  => 'required',
    );

}

As you can see these classes simply contain the validation rules. You can read more on Laravel 4 validation in the docs. For now we’ll simply mark the title and body fields as required.

Now that we have our validators setup, we need to call them upon form submission. We’ll do that in our admin controllers. It’s done by simply creating an instance of our validator and running the passes() method.

app/controllers/admin/ArticlesController

<?php namespace App\Controllers\Admin;

use App\Models\Article;
use App\Services\Validators\ArticleValidator;
use Input, Notification, Redirect, Sentry, Str;

class ArticlesController extends \BaseController {

    public function index()
    {
        return \View::make('admin.articles.index')->with('articles', Article::all());
    }

    public function show($id)
    {
        return \View::make('admin.articles.show')->with('article',Article::find($id));
    }

    public function create()
    {
        return \View::make('admin.articles.create');
    }

    public function store()
    {
        $validation = new ArticleValidator;

        if ($validation->passes())
        {
            $article = new Article;
            $article->title   = Input::get('title');
            $article->slug    = Str::slug(Input::get('title'));
            $article->body    = Input::get('body');
            $article->user_id = Sentry::getUser()->id;
            $article->save();

            Notification::success('The article was saved.');

            return Redirect::route('admin.articles.edit', $article->id);
        }

        return Redirect::back()->withInput()->withErrors($validation->errors);
    }

    public function edit($id)
    {
        return \View::make('admin.articles.edit')->with('article', Article::find($id));
    }

    public function update($id)
    {
        $validation = new ArticleValidator;

        if ($validation->passes())
        {
            $article = Article::find($id);
            $article->title   = Input::get('title');
            $article->slug    = Str::slug(Input::get('title'));
            $article->body    = Input::get('body');
            $article->user_id = Sentry::getUser()->id;
            $article->save();

            Notification::success('The article was saved.');

            return Redirect::route('admin.articles.edit', $article->id);
        }

        return Redirect::back()->withInput()->withErrors($validation->errors);
    }

    public function destroy($id)
    {
        $article = Article::find($id);
        $article->delete();

        Notification::success('The article was deleted.');

        return Redirect::route('admin.articles.index');
    }

}

app/controllers/admin/PagesController

<?php namespace App\Controllers\Admin;

use App\Models\Page;
use App\Services\Validators\PageValidator;
use Input, Notification, Redirect, Sentry, Str;

class PagesController extends \BaseController {

    public function index()
    {
        return \View::make('admin.pages.index')->with('pages', Page::all());
    }

    public function show($id)
    {
        return \View::make('admin.pages.show')->with('page', Page::find($id));
    }

    public function create()
    {
        return \View::make('admin.pages.create');
    }

    public function store()
    {
        $validation = new PageValidator;

        if ($validation->passes())
        {
            $page = new Page;
            $page->title   = Input::get('title');
            $page->slug    = Str::slug(Input::get('title'));
            $page->body    = Input::get('body');
            $page->user_id = Sentry::getUser()->id;
            $page->save();

            Notification::success('The page was saved.');

            return Redirect::route('admin.pages.edit', $page->id);
        }

        return Redirect::back()->withInput()->withErrors($validation->errors);
    }

    public function edit($id)
    {
        return \View::make('admin.pages.edit')->with('page', Page::find($id));
    }

    public function update($id)
    {
        $validation = new PageValidator;

        if ($validation->passes())
        {
            $page = Page::find($id);
            $page->title   = Input::get('title');
            $page->slug    = Str::slug(Input::get('title'));
            $page->body    = Input::get('body');
            $page->user_id = Sentry::getUser()->id;
            $page->save();

            Notification::success('The page was saved.');

            return Redirect::route('admin.pages.edit', $page->id);
        }

        return Redirect::back()->withInput()->withErrors($validation->errors);
    }

    public function destroy($id)
    {
        $page = Page::find($id);
        //$page->delete();

        Notification::success('The page was deleted.');

        return Redirect::route('admin.pages.index');
    }

}

As you can see the controllers are almost identical for now, we’ll expand that in later part of the tutorial.

So let’s quickly go over what happens here. We created a new instance of the validator ($validation = new PageValidator), and then call the passes() which runs the validation and returns a boolean value.

If the validation fails the error messages are available through $validation->errors. You can of course create a getter for the errors, but I like to keep it simple.

The abstract validator class looks for the input data (Input::all()) if no data is passed when instantiating the class, so this cleans up our controller code a bit.

The passes() method simply creates an instance of the Laravel validator, runs the validation and returns true if the validation passes, or stores the errors inside the $errors variable and returns false.

Front end

Now that we have our basic backend setup and working, we need to somehow access the entered articles and pages on the front end. For now we just display the Laravel welcome page when hitting the home page.

I like to create a directory inside the public folder: public/site

And inside this directory, for now we’ll create 2 more directories called views and assets, which is pretty self-explanatory.

My way is to create 3 directories under assets: css, img and js. And also 1 directory under the views dir called **_partials**.

A lot of people are familiar with the basic template hierarchy in WordPress so we’ll do something similar in our theme views. You can also use Blade layouts like we did in our backend, but the theme will be very simple so there’s really no need for it.

The first view that we’ll create is the home page view, and 2 partials, header and footer. Our files should look something like this:

public/site/views/_partials/header.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Laravel 4 Tutorial</title>
</head>
<body>
<div id="layout">
    <header>
        <h1><a href="{{ URL::route('home') }}">Laravel 4 Tutorial</a></h1>
    </header>

    <hr>

public/site/views/_partials/footer.blade.php

   <hr>

    <footer>
        <p>&amp;copy; 2013, Boris Strahija</p>
    </footer>
</div><!--/#layout-->
</body>
</html>

public/site/views/index.blade.php

@include('site::_partials/header')

<h2>Home</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima, temporibus, accusamus, nostrum veritatis doloremque officiis quaerat nulla eius laudantium pariatur iste maxime quam nemo eligendi dignissimos iure consequuntur voluptas nihil!</p>
<p>Qui, veniam, ipsum, reprehenderit, facilis dolore excepturi ipsam doloribus consequatur blanditiis quae nobis fugiat accusamus voluptate quibusdam asperiores architecto ratione! Unde, rem a blanditiis nostrum et explicabo qui est doloremque?</p>

@include('site::_partials/footer')

You can see here that we are referencing the site:: namespace for our views, which doesn’t work for now.

We also need to create routes that will display the content in the right view. So how do we do that? What I like to do is treat this site directory (theme) as a package, and in Laravel a package has it’s service provider.

I recently wrote an article on modules in Laravel 4 where I leveraged these service providers to register and boot up non-composer packages. You can find the article here if you’re interested: http://creolab.hr/2013/05/modules-in-laravel-4/

So to do something similar for our theme, I’ll create a class called SiteServiceProvider, but we also need to add the public/site directory to our composer.json file for autoloading:

composer.json

"autoload": {
    "classmap": [
        "public/site"
    ]
}

public/site/SiteServiceProvider.php

<?php namespace App\Site;

class SiteServiceProvider extends \Illuminate\Support\ServiceProvider {

    public function boot()
    {
        $this->package('app/site', 'site', public_path() . '/site');
    }

    public function register()
    {
        require public_path() . '/site/routes.php';
    }

}

As you can see the service provider registers our site as a package, but we also include the filepublic/site/routes.php which doesn’t exist yet, so we need to create it. But first let’s delete our route for the home page from app/routes.php. To load our home page template we need to add the route:

public/site/routes.php

<?php

Route::get('/', array('as' => 'home', function() {
    return View::make('site::index');
}));

So now when we hit the home page, we should get our index template.

But we also need templates for displaying a single page, a list of articles and a single article. For now this will be enough, so let’s go ahead and create those views:

public/site/views/page.blade.php

@include('site::_partials/header')

<h2>{{ $entry->title }}</h2>
{{ $entry->body }}

@include('site::_partials/footer')

public/site/views/article.blade.php

@include('site::_partials/header')

<h2>{{ $entry->title }}</h2>
<h4>Published at {{ $entry->created_at }} &amp;bull; by {{ $entry->author->first_name }}</h4>
{{ $entry->body }}

@include('site::_partials/footer')

public/site/views/articles.blade.php

@include('site::_partials/header')

<h2>Articles</h2>

<ul>
    @foreach ($entries as $entry)
        <li>
            <h3>{{ $entry->title }}</h3>
            <h5>Created at {{ $entry->created_at }} &amp;bull; by {{ $entry->author->email }}</h5>
            {{ Str::limit($entry->body, 100) }}
        </li>
    @endforeach
</ul>

@include('site::_partials/footer')

To actually display some content we need to create some pages and articles. I updated our content seeder class, but if you prefer to do it manually fell free to do so.

If you prefer the seeder, take a look at https://github.com/bstrahija/l4-site-tutorial/blob/master/app/database/seeds/ContentSeeder.php since I will be working with this data.

Now, when we hit the home page, we want to display the Welcome page which I defined in our content seeder. This page has the slug welcome so we’ll need to modify our home page route to fetch the page:

public/site/routes.php

<?php

Route::get('/', array('as' => 'home', function() {
    return View::make('site::index')
               ->with('entry', App\Models\Page::where('slug', 'welcome')->first());
}));

This should work, but as you can see we are referencing our Page model with the full namespace path. To keep it cleaner we can define an alias in our app/config/app.php file. Just add the following lines under the aliases config::

app/config/app.php

'Article'         => 'App\Models\Article',
'Page'            => 'App\Models\Page',

So now we can cleanup our route like this:

public/site/routes.php

Route::get('/', array('as' => 'home', function() {
    return View::make('site::index')
               ->with('entry', Page::where('slug', 'welcome')->first());
}));

And now that we pass the welcome page to the view, we can adapt our view like this:

public/site/views/index.blade.php

@include('site::_partials/header')

<h2>{{ $entry->title }}</h2>
{{ $entry->body }}

@include('site::_partials/footer')

Now that we have our welcome page setup, we need to define the routes for our articles and pages. The URL’s will look like this:

Let’s first deal with the list of articles (and keep in mind I will be doing most of the things directly inside the routes file, some people prefer controller but I guess for simple stuff this is ok):

public/site/routes.php

Route::get('blog', array('as' => 'article.list', function() {
    return View::make('site::articles')
               ->with('entries', Article::orderBy('created_at', 'desc')->get());
}));

We want to order the articles by date, so that the newest article is always on top. Now go ahead and hit the URL /blog and you should get a list of article through the template articles.blade.php.

They’re not linked to the single page yet, well get to that immediately:

public/site/routes.php

Route::get('blog/{slug}', array('as' => 'article', function($slug) {
    return View::make('site::article')
               ->with('entry', Article::where('slug', $slug)->first());
}));

If you used my content seeder you should be able to go to the URL: /blog/first-post and get the article displayed in the article.blade.php template.

The list of articles is that useful without actually linking to the articles details, and that’s why we created named routes. You can read more on that in the Laravel 4 docs: http://laravel.com/docs/routing#named-routes

The name for the single article route is article so to link our articles we need to adapt our articles.blade.php view:

public/site/views/articles.blade.php

@include('site::_partials/header')

<h2>Articles</h2>

<ul>
    @foreach ($entries as $entry)
        <li>
            <h3><a href="{{ URL::route('article', $entry->slug) }}">{{ $entry->title }}</a></h3>
            <h5>Created at {{ $entry->created_at }} &amp;bull; by {{ $entry->author->email }}</h5>
            {{ Str::limit($entry->body, 100) }}
        </li>
    @endforeach
</ul>

@include('site::_partials/footer')

And on the details page we’ll add a “back” link to the list of articles:

public/site/views/article.blade.php

@include('site::_partials/header')

<h2>{{ $entry->title }}</h2>
<h4>Published at {{ $entry->created_at }} &amp;bull; by {{ $entry->author->email }}</h4>
{{ $entry->body }}

<hr>

<a href="{{ URL::route('article.list') }}">&amp;laquo; Back to articles</a>

@include('site::_partials/footer')

The final thing we have left is the route to the pages. There was one problem I found here. Since the route is the slug of the page, and the admin route is also considered a slug, I got an error. So until I find a better solution I added where statement at the end of the route that ignores the adminroute:

public/site/routes.php

Route::get('{slug}', array('as' => 'page', function($slug) {
    return View::make('site::page')
               ->with('entry', Page::where('slug', $slug)->first());
}))->where('slug', '^((?!admin).)*$');

The page.blade.php template is already setup so when hitting /about-us you should see the content from that page.

The basic front end functionality for Laravel 4 site is now ready, but we don’t have our pages linked.

To conclude this part of the tutorial we’ll also create a navigation partial. So go ahead and create the file:

public/site/views/_partials/navigation.blade.php

<nav>
    <ul>
        <li><a href="{{ URL::route('home') }}">Home</a></li>
        <li><a href="{{ URL::route('page', 'about-us') }}">About us</a></li>
        <li><a href="{{ URL::route('article.list') }}">Blog</a></li>
        <li><a href="{{ URL::route('page', 'contact') }}">Contact</a></li>
    </ul>
</nav>

The navigation is hardcoded for now, but for simple websites this is fine. Keep in mind that I’m working with named routes, you need to follow the route creation exactly if you want the same result, or else you’ll get an exception.

Finally we’ll include the partial in our header:

public/site/views/_partials/header.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Laravel 4 Tutorial</title>
</head>
<body>
<div id="layout">
    <header>
        <h1><a href="{{ URL::route('home') }}">Laravel 4 Tutorial</a></h1>

        @include('site::_partials.navigation')
    </header>

    <hr>

Try clicking on the links and see if everything works fine.

What’s next?

In the next part we’ll cover custom error pages for our theme, adding some style to the theme and image uploading and resizing. Until then, express your thoughts in the comments section below.

The fourth part on Laravel 4 images, themes and error pages…

Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedInShare on RedditShare on StumbleUpon



  • uldis

    Wondering, why you are keeping views, routes, service providers in public folder?

    • I just wanted to have the entire theme inside 1 directory, and not complicate things with publishing assets. You can of course put the “site” dir wherever you want just keep in mind that the assets need to be publicly available.

      • Yes, same with me, its more convinent to put views, and all public asset into /public 🙂

  • plexnum

    I think validation should be in a model. because validation make model always valid it’s like an invariant in oop. Why you make partials? i think you should use layout and sections it’s mach more better approach because it exclude redundancies in each view. if you use layout you don’t need to include each partial in each view. Why you create service provider just for defining routes and define namespaces?

    • plexnum

      Becouse goal of service provider define services but you not define ones

    • It’s a matter of preference, I like separating validation from models because in a real world you don’t validate only models but lots of other stuff like eg. a contact form. There are many ways to do validation, this is just the one I like the most.

      Partials/layouts – again, a matter of preference. I don’t see this as an issue in a small site like that. Maybe I’ll refactor some of the stuff in later parts.

      Service provider – I consider the “site” folder to be a package, and to bootstrap a package I use a service provider. I don’t see anything wrong with that. A “service” is a very broad term, so the frontend routes, templates etc. can also be considered as a service.

  • mikadamczyk

    Thank you for your work.

  • Peter

    Hi,

    this is an amazing tutorial series. Thank you for that!
    I would like to suggest though to add some common features people are looking for, like:

    -Image uploading
    -Filtering the table using json

    • It says image uploading/resizing is coming in the next part. The API part will come a little later.

      • Peter

        Thanks,
        as I wasn’t sure about my comment being published I wrote the same question as on your github.

        Sorry for the inconvenience.

  • tashi

    you are the man!!!

    thanks. greats tutorial.

    eagerly waiting for the next part…….

  • Mounir

    for the next part with the imagine library, could you please show us how to use it’s crop and thumbnails making, also how to store the link to the database too 🙂

  • Martin

    Hi Boris, I’m getting Error 310 (net::ERR_TOO_MANY_REDIRECTS): when accessing at /public/site

    • Do you have the latest L4 version, is your .htaccess file setup properly? Does a default L4 installation work properly?
      If not, please consult the L4 docs, and setup a working copy of L4 first.

  • Martin

    Also, Accessing /public gives me

    Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException.

    If I move routes directive to /app/routes.php gives me

    InvalidArgumentException
    No hint path defined for [site].

    Thanks in advance.

    • Try comparing the code from github with your copy. That works 100%.
      It’s hard to tell what’s different and whats causing your problems.

      • I had the same problem and hadn’t registered the site as a ServiceProvider in /app/config/app.php – worked fine then.

        Thanks for the excellent tutorials – can’t wait for the next part 🙂

        • Nate

          I registered site as a ServiceProvider inside config/app.php and I am still getting the same No hint path defined for [site] error message.

          ‘Krucas\Notification\NotificationServiceProvider’,
          ‘App\Site\SiteServiceProvider’

          ),

          Also added to composer.json….

          “classmap”: [
          “public/site”

          Started from scratch and still getting the same error message.

          • I don’t know how to help you. Put up your project somewhere so I can take a look.

    • Neo

      You have to actually create the folders. For instance create the lang, config, and views folders and try again. That solved it for me.

  • Martin

    Hi Boris, somehow L4 can’t register site as a package, I solved moving site files to conventional /views folder and routes directives to app/routes and now is working.

    I had some inconvinience with ->belongsTo(‘User’) in Articles as well, so I added its alias to app/config/app and replaced with ->belongsTo(‘User’,’user_id’) and now its workins.

    Thanks a bunch.

    • Make sure you’ve got the site registered in /app/confog/app.php (check the ServiceProviders section against the one on Github)

  • idriss

    Thank you very much for this great tutorial!

  • Ian

    I’ve been learning & working with Laravel for a while, but I never felt like I ‘got it’ until these tutorials. Great work!

  • Nick

    Hi Boris,

    Thank you for this excellent tutorial and could you please let me know when the next part will be available ?

    • I hope sometime next week. I have to see how much I’ll have available.

  • Mezigh

    Hi very nice serie.
    I have a request- You choose to use Cartalyst Sentry for
    Managing and Auth concerns but in your website there’s only a single user which is admin. What about ( like in most case in real world example ) add the ability to have more users with different permissions for each and more groups. Doing it that way you really optimize Sentry which is absolutely awesome for this purpose
    Olivier

  • Mourad Hamoud

    I think the “Validator” class should be renamed to “AbstractValidator” to avoid confusion.

    Thank you for this nice tutorial 😉

  • Karim

    When I try to look at the articles list at /blog I get the ” Trying to get property of non-object” error. It does the same error when I try to access a single article (/blog/first-post). I checked my code with Github, it was the same. I even installed the 0.3.0 Github copy and I still get this error. Any ideas?

    • Karim

      Found it. My admin@admin user had a id value of “4” for some reasons. So that author->email was returning null in the article and article views.

      • applecrusher

        What should it be instead “1”? I am having the same problem.

        • applecrusher

          I didn’t think changing it the 1 would help but it did and I understand why now. It’s because the author’s id was 1. Sorry for the question

    • Kat

      When seeding, your user_id may deviate from the first id entered in users table. Make sure the user_id in the Pages/Articles table matches an existing record in the users table.

  • Karim

    These tutorials are excellent. We are craving for part 4. Any clue on when you gonna have some time to post it online Boris?

    • I’m currently buried with work, but I think I will be able to finish it next week.

  • jenchi

    I have a problem with validations, file precisely validator.php, some symbols does not detect the browser and when calling the class passes () I mark the following error syntax error, unexpected ‘if’ (T_IF) in the if . and I check all code I tested and I can not fix it. Can you help me. Your tutorial is wonderful congratulations has served me well to start learning Laravel

    • You’re probably missing a “;” somewhere. Grab a decent code editor that will point out syntax errors (Sublime Text 2 + Sublime Linter).

      • jenchi

        I corrected the error but now I get the following error Class ‘PageValidator’ not found, when you enter the store function, and I put the namespace but does not work, by the way I’m using 4.05 laravel

  • jenchi

    corrected the problem and the solution was to update the list of autoload the composer, but now I went the following error, Call to undefined method PageValidator :: passes () this is the code that I have. This well written?
    validator.php
    data = $ data: \ Input :: all ();
         }

         / **
          * Check if validation passes
          * @ Return bool
          * /
         public function passes ()
         {
             $ validaction = Validator :: make ($ this-> data, static :: $ rules);

             if ($ validation-> passes ()) return true;

             $ this-> errors = $ validation-> messages ();

             return false;
         }

    }

  • Jon

    Hi Boris,

    Great tut, really helping me out thanks.

    I’ve cloned the repo and have it up and running with the site package and then took the relevant models,views and controllers, sentry migrations and all seed data on to my own project’s installation. I want to implement an admin area with sentry.

    I have it working fine on my project but when trying to duplicate the pages admin route to a controller named ‘Areas’ I get the following error:

    http://bit.ly/14DcH5Z

    The strange thing, I’ve just duplicated the PagesController and altered the name. I even took out the Controller methods.

    Any ideas?

    Thanks a lot Boris.

    Jon from England.

    • Jon

      That screengrab of my code only showed my routes.php and the model – here’s AreasController.php

      http://bit.ly/14DdG6b

  • Jon

    Ahh I’ve found the answer. I should have autoloaded in composer

    php composer.phar dump-autoload

  • tanzeel

    I did everything as in the tutorial. there are some files that are automatically generated and there is an error in them

    “ErrorException
    Trying to get property of non-object

    make(‘site::_partials/header’, array_except(get_defined_vars(), array(‘__data’, ‘__path’)))->render(); ?>

    title; ?>
    body; ?>

    make(‘site::_partials/footer’, array_except(get_defined_vars(), array(‘__data’, ‘__path’)))->render(); ?>

    the error is on line 3 which is this : “title; ?>”

    I am unable to resolve this issue can someone help

    • tanzeel

      Fixed it

      Views/index.blade.php :

      @include(‘site::_partials/header’)

      {{ $entry[‘title’] }}
      {{ $entry[‘body’] }}

      @include(‘site::_partials/footer’)

      $entry -> title can not be used as it is is object notation, which can only be used to access object attributes and methods.

      • If you pass an array to the view it wont work, but I’m passing an Eloquent object so “$entry->title” works without problems for me. Take a look at the code on github.

        • Kholid

          i have an error like tanzeel too
          ———————————
          ErrorException
          Trying to get property of non-object
          open: D:\xampp\htdocs\LARAVEL\l4-site-tutorial\app\storage\views6f6dded674934663866f9a9dcb1c3bb
          make(‘site::_partials/header’, array_except(get_defined_vars(), array(‘__data’, ‘__path’)))->render(); ?>

          title; ?>
          body; ?>

          make(‘site::_partials/footer’, array_except(get_defined_vars(), array(‘__data’, ‘__path’)))->render(); ?>
          —————————————–

          And i try tanzeel solution, no error but result 404 pages not found..
          How can i resolve, help me..

  • tanzeel

    If I the public site to be authenticated before people can access the articles and pages do I need another filters file ? or can I use the same filters file in my app directory ?

    • If you want the same functionality and the same login screen, you can use the same filter.

  • Nice tutorials, thanks for the source. Im going to wait impatient for the image class 😀

  • Sarino Grasso

    Hi Boris, your tutorials have been very helpful. Thanks.

    I have a question about validation. Suppose you want to validate that the slug of the Article is unique. You can just add the Laravel “unique” rule, but what about when you want to edit the Article and you need to ignore that slug.

    How could you implement that using the validation patter in the tutorial?

  • bhoopal

    when single file upload
    Input::upload(‘image’,’path/to’,’picture.jpg’); is working
    but when i am upload multiple image
    Input::upload(‘image[$i]’,’path/to’,’picture.jpg’); is not working anyone can resolve me

  • Matt

    Quick question…I’m using your validator setup to validate a form that is re-used as both an Add/Edit form.

    One of the fields has to be unique. Naturally when editing the form, since that field data already exists in the database the validator doesn’t pass.

    Is there an easy way to update the rules on the fly as you have it set up, preferably so I can pass a variable to detect if the add rules or edit rules need to be applied?

  • Dau

    I implement your validator class and get error:

    Undefined class constant ‘rules’

    At line:

    $validation = \Validator::make($this->data, static::$rules);

    Can you help me out?

  • Daniel Veres

    Hi,

    I went trough your tutorial. Thanks it seems to be useful, but I would like to ask you how to load asset files?

    I tried both my own code and yours from github with no luck. main.css gives me 404 error when i try to run the app using laravel’s built-in server. (php -S localhost:8000 server.php) (php version: 5.4.19)

    Thanks

  • Johan Nielsen

    Hi, Great tutorial you made. I just want to ask where the markdown part comes into play when we install it with composer?

    • I was planning to include a nice markdown editor in the admin part.

  • Elmo

    Could someone please refer me a link to the documentation for the operator:

    Object->

    Thanks.

    • Elmo

      Sorry, part of the text was filtered

      the operator i am curious about is the one used on line 18 of the seconf snippet

      $this – & gt ;

      • I’s some kind of a WordPress problem with escaping chars. I’ll have to fix this.
        There is no such operator 😉

  • Arturas

    My composer.json autoload section looks like:
    “autoload”: {
    “classmap”: [
    “app/commands”,
    “app/controllers”,
    “app/models”,
    “app/database/migrations”,
    “app/database/seeds”,
    “app/tests/TestCase.php”,
    “app/services”,
    “public/site”,
    “app/facades”
    ]
    },

    my app/config/app.php providers section also has:
    ‘App\Site\SiteServiceProvider’,

    When I try to enter command:
    -jailshell-3.2$ php artisan dump-autoload

    I’ve got error message:

    {“error”:{“type”:”Symfony\\Component\\Debug\\Exception\\FatalErrorException”,”message”:”Class ‘App\\Site\\SiteServiceProvider’ not found”,”file”:”\/home\/xxx\/host\/laravel\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/ProviderRepository.php”,”line”:123}}-jailshell-3.2$

    Everything have copied from github.

    Cannot solve the reason, why cannot find SiteServiceProvider.php in public/site/

    • The problem is you’re running “artisan” when there are service providers in your list that can’t be found yet and as artisan is a part of laravel, and most of it’s commands take advantage of those service providers, that’s why it fails.

      What you need to do is run “composer dump”.

  • Karim

    How do you use a Controller with your site package?

    I tried add a controllers directory in site and to add the classmap

    “public/site/controllers”

    Then I made my route:

    Route::get(‘home’, array(‘as’ => ‘home’, ‘uses’ => ‘site\HomeController@ShowHome’));

    And my controller looks like:

    <?php namespace site\controllers;

    class ModalController extends \BaseController {

    public function ShowHome()
    {
    return View::make('site::home')
    }}

    Then I ran dump auto-load but it don't get to my controller

    When I run php artisan route, the route appear as stated in routes.php.

    Any clue Boris?

  • akira

    this is really awesome tutorial for newbie like me.
    i had a lame question which, i want to create a contact form in this page. however i can’t manage to solve it. even i set is this in routes.php :

    Route::any(‘contact-us’, function()
    {
    return ‘Hello World’;
    });

    i keep show me 404 error. any advice to solve this. been look for this almost 2 days :(. please help.

  • What is your preferred way to add custom validation rules to the service? Say you wanted to add a custom validation to PageValidator

  • Eric Gauvin

    Thanks, Boris!

  • kalai arasan

    Hi boris, It is really a nice tutorial for newbie. I have downloaded the files from git and uploaded into my local ubuntu system. But it is showing blank page when go the public folder through the URL. Can you please explain me the problem.