Простой блог на фреймворке Laravel 5

25.08.2015

Вступление

Данная статья рассчитана на тех, кто знаком с олдскульным php и хочет поднять\обновить свой уровень, познакомившись с разработкой на прогрессивном фреймворке.

Много лет назад я написал CMS для своего блога на чистом php с БД на файлах, глобальная паутина не стоит на месте и уже давно пришло время все переделывать. 
Тратить много времени на блог не хочется, но и в очередной раз использовать WordPress тоже нет желания, захотелось поиграться с Laravel и в результате получилась эта статья и новая CMS для блога.  
То что Вы сейчас видите на сайте - уже новая версия, сделанная на нем.  
В этой статье я опишу как начать разрабатывать блог на laravel 5 c MySQL. 
Сделать блог на этом фреймворке очень просто, но не на столько, чтобы у меня нашлось время сделать полноценный туториал от начала до конца. Я думаю это и не нужно, главное начать, а дальше пойдет)
Если хотите полностью код со всеми коммитами, ищите у меня на визитке ссылку на аккаунт на github, подписывайтесь, клонируйте движок.

Начнем

Первое что нам понадобится - composer. Это менеджер пакетов для php, если у Вас его еще нет, скачайте.
Для разработки нам не понадобиться apache, поэтому можете разместить разрабатываемый проект в любом месте.
Открываем консоль в директории для новго проекта и создаем его: 

php ~/composer.phar create-project laravel/laravel blog --prefer-dist

В конце процесса произойдет следующее:

Writing lock file
Generating autoload files
> php artisan clear-compiled
> php artisan optimize
Generating optimized class loader
> php artisan key:generate
Application key [b5mKGElpPyubRvd51BU0aJ5ey8ScDwC1] set successfully.

Обращаю внимание, что если просто склонировать laravel из git, то эти команды сами не выполнятся.
php artisan key:generate генерирует секретный ключ для приложения и без него ничего не запустится. 
У нас это сделалось автоматически. 
Уже есть файл .gitignore, который поможет избежать попадания в git-репозиторий конфигов, кеша, логов и других файлов, которым там не место. 

В .env указываем актуальные настройки для mysql, выполнил unit-test ExampleTest и запустил встроенный сервер

php artisan serve


На странице http://localhost:8000/ теперь можно наблюдать надпись "Laravel 5". Отлично.

Добавляем через composer помошник HTML форм:
composer require laravelcollective/html
и добавляем его в config/app.php

 'providers' => [
        ...
        Collective\Html\HtmlServiceProvider::class,
    ]
    ...
    'aliases' => [
        ...
        'Form'      => Collective\Html\FormFacade::class,
        'Html'      => Collective\Html\HtmlFacade::class,
    ]
    


также в этом файле есть опция url, которую лучше вынести в env:

...
'url' => env('APP_URL', 'http://localhost'),
...

Приступаем к коду. 
Для создания модели выполним:

php artisan make:model Article --migration


Кроме класса модели создался файл в database/migrations
Добавляем в него нужные нам поля, например так:

        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('path')->nullable();
            $table->text('content');
            $table->text('small')->nullable();
            $table->integer('comments', false, true)->default(0);
            $table->timestamps();
        });

в самой модели указываем какие поля можно присваивать
protected $fillable = ['title', 'path', 'content', 'small'];

Создаем таблицы в БД:

php artisan migrate

Генерируем контроллер:

php artisan make:controller ArticlesController

Добавляем маршрут в app/Http/routes.php
Route::resource('articles', 'ArticlesController');

В контроллере уже созданы основные методы, но нужно их заполнить, например так: 

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Article;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class ArticlesController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        $articles = Article::orderBy('id', 'desc')->paginate();
        return view('articles.index', compact('articles'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create()
    {
        $article = new Article;
        return view('articles.create', compact('article'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        Article::create($request->all());
        return redirect('articles');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return Response
     */
    public function show($id)
    {
        $article = Article::where('id', $id)->firstOrFail();
        return view('articles.show', compact('article'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return Response
     */
    public function edit($id)
    {
        $article = Article::where('id', $id)->firstOrFail();
        return view('articles.edit', compact('article'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  Request  $request
     * @param  int  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        $article = Article::where('id', $id)->firstOrFail();
        $article->update($request->all());
        return redirect('articles');

    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return Response
     */
    public function destroy($id)
    {
        Article::where('id', $id)->delete();
        return redirect('articles');
    }
}

Никакой проверки прав пока еще нети чтобы это работало нужно создать view в resources/views/articles/
blade шаблон для главной:
resources/views/articles/index.blade.php

{!! link_to_route('articles.create', 'Новый пост') !!}

@foreach ($articles as $article)
    <article>
        <h3>{!! link_to_route('articles.show', $article->title, $article->id) !!}</h3>
        <div>
            {!! link_to_route('articles.edit', 'Редактировать', $article->id) !!}
            {!! Form::open(['method' => 'DELETE', 'route' => ['articles.destroy', $article->id]]) !!}
            <button type="submit">Удалить</button>
            {!! Form::close() !!}
        </div>
        {!! $article->small !!}
        <div>Комментариев: {{ $article->comments }}</div>
    </article>
    <hr>
    @endforeach

<!-- pagination -->
{!! $articles->render() !!}

resources/views/articles/show.blade.php

<article>
    <h1>{{ $article->title }}</h1>
    <div>{!! $article->content !!}</div>
</article>
{!! link_to_route('articles.index', 'Все статьи') !!}

resources/views/articles/create.blade.php

{!! Form::open(['route' => 'articles.store']) !!}
@include ('articles.form', ['submitButtonText' => 'Запостить'])
{!! Form::close() !!}

resources/views/articles/edit.blade.php

{!! Form::model($article, ['method' => 'PATCH', 'route' => ['articles.update', $article->id]]) !!}
@include ('articles.form', ['submitButtonText' => 'Обновить'])
{!! Form::close() !!}

resources/views/articles/form.blade.php

<div>
    {!! Form::label('title', 'Заголовок:') !!}
    {!! Form::text('title') !!}
</div>
<div>
    {!! Form::label('path', 'Адрес для ЧПУ:') !!}
    {!! Form::text('path') !!}
</div>

<div>
    {!! Form::label('content', 'Контент:') !!}
    {!! Form::textArea('content') !!}
</div>
<div>
    {!! Form::label('small', 'Короткий текст:') !!}
    {!! Form::textArea('small') !!}
</div>
{!! Form::submit($submitButtonText) !!}

Желательно унаследовать их все от общего шаблона, например 

@extends('main')
@section('content')
...
@endsection

тогда в файле resources/views/main.blade.php нужно поместить шаблон с тегами HTML /HTML и с конструкцией 

@yield('content')


в том месте, где должен выводиться контент.

Итого, мы уже имеем базовый функционал блога: добавление, редактирование, удаление и постраничный просмотр статей. 

В следующем посте я расскажу как не напрягаясь сделать подгрузку постов по мере скроллинга и организовать frontend разработку.


4 оценки
Комментарии
seoonly.ru:
Спасибо) Для простого проекта пойдет
Юрий:
Скачал, поставил win-7 open-server, при публикации поста в админке выдает ошибку
ErrorException in helpers.php line 454:
htmlentities() expects parameter 1 to be string, array given (View: C:\OpenServer\domains\larablog\resources\views\admin\post\create.blade.php)
in helpers.php line 454
at CompilerEngine->handleViewException(object(ErrorException), '0') in compiled.php line 14236
at PhpEngine->evaluatePath('C:\OpenServer\domains\larablog\storage\framework\views/8a3bb1bd4cec2762dc303227fd9e2fd4', array('__env' => object(Factory), 'app' => object(Application), 'errors' => object(ViewErrorBag), 'tags' => '[]', 'categories' => object(Collection))) in compiled.php line 14270

И еще 68 строк описания ошибок

Пункт Categories пустой в админке, может категории как то вручную нужно создать?
Или может проблема в windows....
Юрий:
Что то не получается пока... обязательно нужно проделывать то что здесь описано или достаточно выполнить то что написано на Github?
Пытался добавлять как здесь описано - все равно ошибку выдает в конце инсталляции...
> php artisan clear-compiled



[Symfony\Component\Debug\Exception\FatalErrorException]
Class 'Collective\Html\HtmlServiceProvider::class' not found



Script php artisan clear-compiled handling the post-update-cmd event returned with an error



[RuntimeException]
Error Output:
Юрий:
Второй вопрос вроде как решился, нужно в composer.json добавить кое чего:
Begin by installing this package through Composer. Edit your project's composer.json file to require laravelcollective/html.

"require": {
"laravelcollective/html": "5.1.*"
}
Next, update Composer from the Terminal:
Никита:
На гитхабе в composer.json уже есть
"require": {
"laravelcollective/html": "5.1.x-dev",
}

там дана инструкция

git clone https://github.com/Hukuta/laravel-blog.git && cd laravel-blog/
php $YOUR_PATH_TO_COMPOSER/composer.phar install

У Вас полностью это выполнилось успешно?
Вы указали $YOUR_PATH_TO_COMPOSER?

Отвечаю на Ваш вопрос, данная статья просто поясняет как получилось часть того, что уже готово на гитхабе, поэтому выполнять действия из нее не обязательно в случае выполнения инструкций с гитхаба и клонирования репозитория, но можно их взять на вооружение для создания других проектов.

>Пункт Categories пустой в админке, может категории как то вручную нужно создать?

извините, но я не понял где Вы нашли там админку и Categories
Юрий:
Блин, прости пожалуйста, я напутал вот с этим https://github.com/mydnic/Larablog
Извини пожалуйста... вот я чайник:)

Оставить комментарий