git clone https://github.com/cartalyst/platform.git blog
Navigate into the downloaded folder and run
composer install
Platform can be installed either through the browser or terminal,
Navigate to your vhost, the installer will appear, follow instructions.
run php artisan platform:install
and follow instructions.
Note If you want platform to install the extension for you, make sure you create a
workbench
directory that is writable by the webserver in your project root before proceeding with the next step.
Open the app in the browser, Sign in, go to Admin
Under Operations choose Workshop
Fill out the fields as follows
Author Name: Cartalyst Author Email: [email protected] Vendor: cartalyst Name: blog Version: 0.1.0 Description: A Platform 2 Blog Extension
Components: Admin components Frontend components
Install Method: Automatic
Click on Save
We'll start by defining our routes on workbench/cartalyst/blog/extension.php
under routes around #186 we'll define our routes as follows
// Admin routes
Route::group(array('prefix' => admin_uri().'/blog', 'namespace' => 'Cartalyst\Blog\Controllers\Admin'), function()
{
Route::get('/', 'BlogController@index');
Route::get('grid', 'BlogController@grid');
Route::get('create', 'BlogController@create');
Route::post('create', 'BlogController@store');
Route::get('{id}/edit', 'BlogController@edit');
Route::post('{id}/edit', 'BlogController@update');
Route::get('{id}/delete', 'BlogController@delete');
});
// Frontend routes
Route::group(array('prefix' => 'blog', 'namespace' => 'Cartalyst\Blog\Controllers\Frontend'), function()
{
Route::get('/', 'BlogController@index');
Route::get('{id}', 'BlogController@show');
});
Now, let's create our blog migrations
Navigate to your project directory in the terminal,
run php artisan migrate:make create_posts_table --path="workbench/cartalyst/blog/database/migrations" --create posts
Now we need to add title and body fields to our migration, navigate to the newly created migration and add the missing fields to match the following
Schema::create('posts', function(Blueprint $table)
{
$table->increments('id');
$table->string('title');
$table->text('body');
$table->timestamps();
});
Let's create our Post model .. workbench/cartalyst/blog/src/Post.php
<?php namespace Cartalyst\Blog;
use Eloquent;
use Str;
use Carbon\Carbon;
class Post extends Eloquent {
protected $appends = array('summary');
protected $guarded = array(
'id',
'created_at',
'updated_at',
);
public function getSummaryAttribute($item)
{
return Str::words(strip_tags($this->body), 60, '...');
}
public function getCreatedAtAttribute($item)
{
return Carbon::parse($item)->format('M d, Y');
}
}
<?php namespace Cartalyst\Blog\Controllers\Admin;
use Platform\Admin\Controllers\Admin\AdminController;
use View;
use Input;
use DataGrid;
use Redirect;
use Sentry;
use Platform\Users\Repositories\DbUserRepository as User;
use Cartalyst\Blog\Post;
class BlogController extends AdminController {
/**
* Holds the post instance.
*
* @var \Cartalyst\Blog\Post
*/
protected $post;
/**
* Constructor.
*
* @param \Cartalyst\Blog\Post $post
* @return void
*/
public function __construct(Post $post)
{
parent::__construct();
$this->post = $post;
}
/**
* Datasource for the blogs Data Grid.
*
* @return \Cartalyst\DataGrid\DataGrid
*/
public function grid()
{
return DataGrid::make($this->post->all(), array(
'id',
'title',
'created_at',
));
}
/**
* Return the main administration screen.
*
* @return \Illuminate\View\View
*/
public function index()
{
return View::make('cartalyst/blog::index');
}
/**
* Return create form.
* @param int $id
* @return \Illuminate\View\View
*/
public function create()
{
return $this->showForm('create');
}
/**
* Return edit form.
* @param int $id
* @return \Illuminate\View\View
*/
public function edit($id)
{
return $this->showForm('edit', $id);
}
/**
* Update the specified post.
* @param int $id
* @return \Illuminate\Http\RedirectResponse
*/
public function update($id)
{
$post = $this->post->find($id);
$post->fill(Input::except('_token'));
if ($post->save())
{
return Redirect::toAdmin("blog/{$post->id}/edit")->withSuccess('Post Successfully updated.');
}
else
{
return Redirect::toAdmin('blog')->withSuccess('There was an error updating your post.');
}
}
/**
* Show create / edit form.
*
* @param string $mode
* @param int $id
* @return \Illuminate\View\View
*/
public function showForm($mode, $id = null)
{
$post = $id ? $this->post->find($id) : $this->post;
return View::make('cartalyst/blog::form')->with(compact('post', 'mode'));
}
/**
* Save post.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function store()
{
$input = Input::except('token');
$post = Post::create($input);
return Redirect::toAdmin("blog/{$post->id}/edit")->withSuccess('Post successfully created.');
}
/**
* Remove the specified post.
*
* @param int $id
* @return \Illuminate\Http\RedirectResponse
*/
public function delete($id)
{
// Delete the page
if ($this->post->find($id)->delete())
{
return Redirect::toAdmin('blog')->withSuccess('Post successfully deleted.');
}
return Redirect::toAdmin('blog')->withErrors('An error occured, please try again later.');
}
}
<?php namespace Cartalyst\Blog\Controllers\Frontend;
use Platform\Foundation\Controllers\BaseController;
use View;
use Cartalyst\Blog\Post;
class BlogController extends BaseController {
/**
* Return the main administration screen.
*
* @return Illuminate\View\View
*/
public function index()
{
$posts = Post::paginate(8);
return View::make('cartalyst/blog::index')->with(compact('posts'));
}
/**
* Return the post view.
* @param int $id
* @return \Illuminate\View\View
*/
public function show($id)
{
$post = Post::find($id);
return View::make('cartalyst/blog::show')->with(compact('post'));
}
}
workbench/cartalyst/blog/themes/admin/default/packages/cartalyst/blog/views/datagrid.blade.php
<script type="text/template" data-grid="main" data-template="results">
<% _.each(results, function(r) { %>
<tr>
<td><%= r.title %></td>
<td><%= r.created_at %></td>
<td>
<a class="btn btn-primary tip" href="{{ URL::toAdmin('blog/<%= r.id %>/edit') }}" title="{{{ trans('button.edit') }}}"><i class="fa fa-edit"></i></a>
<a class="btn btn-danger tip" data-toggle="modal" data-target="modal-confirm" href="{{ URL::toAdmin('blog/<%= r.id %>/delete') }}" title="{{{ trans('button.delete') }}}"><i class="fa fa-trash-o"></i></a>
</td>
</tr>
<% }); %>
</script>
<script type="text/template" data-grid="main" data-template="filters">
<% _.each(filters, function(f) { %>
<span>
<button type="button" class="btn btn-info tip" title="{{{ trans('general.remove_filter') }}}">
<% if (f.column === 'all') { %>
<%= f.value %>
<% } else { %>
<%= f.value %> {{{ trans('general.in') }}} <em><%= f.column %></em>
<% } %>
<i class="fa fa-times"></i>
</button>
</span>
<% }); %>
</script>
<script type="text/template" data-grid="main" data-template="no_results">
<tr>
<td colspan="5">No results.</td>
</tr>
</script>
<script type="text/template" data-grid="main" data-template="pagination">
<% _.each(pagination, function(p) { %>
<div>
<div class="pull-right">
<ul class="pagination pagination-sm">
<% if (p.previous_page !== null) { %>
<li><a data-grid="main" data-page="<%= p.previous_page %>"><i class="fa fa-chevron-left"></i></a></li>
<% } else { %>
<li class="disabled"><span><i class="fa fa-chevron-left"></i></span></li>
<% } %>
<% if (p.next_page !== null) { %>
<li><a data-grid="main" data-page="<%= p.next_page %>"><i class="fa fa-chevron-right"></i></a></li>
<% } else { %>
<li class="disabled"><span><i class="fa fa-chevron-right"></i></span></li>
<% } %>
</ul>
</div>
Showing <%= p.page_start %> to <%= p.page_limit %> of <span class="total"><%= p.filtered %></span>
</div>
<% }); %>
</script>
workbench/cartalyst/blog/themes/admin/default/packages/cartalyst/blog/views/index.blade.php
@extends('layouts/default')
{{-- Page title --}}
@section('title')
Blog ::
@parent
@stop
{{-- Queue Assets --}}
{{ Asset::queue('underscore', 'underscore/js/underscore.js', 'jquery') }}
{{ Asset::queue('data-grid', 'cartalyst/js/data-grid.js', 'underscore') }}
{{-- Inline scripts --}}
@section('scripts')
@parent
<script>
$(function() {
var dg = $.datagrid('main', '.data-grid', '.pagination', '.filters', {
loader: '.loading',
scroll: '.data-grid',
callback: function()
{
$('#checkAll').prop('checked', false);
$('#actions').prop('disabled', true);
}
});
});
</script>
@stop
{{-- Page content --}}
@section('content')
<div class="col-md-12">
{{-- Page header --}}
<div class="page-header">
<span class="pull-right">
<a class="btn btn-warning" href="{{ URL::toAdmin('blog/create') }}"><i class="fa fa-plus"></i> Create</a>
</span>
<h1>Blog</h1>
</div>
{{-- Data Grid : Search --}}
<div class="row">
<div class="col-lg-12 text-right">
<form method="post" action="" accept-charset="utf-8" data-search data-grid="main" class="form-inline" role="form">
<div class="form-group">
<div class="loading"></div>
</div>
<div class="form-group">
<select class="form-control" name="column">
<option value="all">All</option>
<option value="title">Title</option>
</select>
</div>
<div class="form-group">
<input name="filter" type="text" placeholder="Search" class="form-control">
</div>
<button class="btn btn-default"><i class="fa fa-search"></i></button>
</form>
</div>
</div>
<br />
{{-- Data Grid : Content --}}
<table data-source="{{ URL::toAdmin('blog/grid') }}" data-grid="main" class="data-grid table table-striped table-bordered table-hover">
<thead>
<tr>
<th data-sort="title" data-grid="main" class="col-md-3 sortable">Title</th>
<th data-sort="created_at" data-grid="main" class="col-md-3 sortable">Created at</th>
<th class="col-md-2"></th>
</tr>
</thead>
<tbody></tbody>
</table>
{{-- Data Grid : Pagination --}}
<div class="pagination" data-grid="main"></div>
</div>
@stop
{{-- Data Grid : Templates --}}
@include('cartalyst/blog::datagrid')
workbench/cartalyst/blog/themes/admin/default/packages/cartalyst/blog/views/form.blade.php
@extends('layouts/default')
{{-- Page title --}}
@section('title')
{{$mode}} Blog Post ::
@parent
@stop
{{-- Page content --}}
@section('content')
<div class="col-md-12">
<div class="page-header">
<h1>{{ucfirst($mode)}} <small>Blog Post</small></h1>
</div>
{{ Form::open() }}
<div class="form-group">
{{ Form::label('title') }}
{{ Form::text('title', Input::old('title', $post->exists ? $post->title : null), array('class' => 'form-control')) }}
</div>
<div class="form-group">
{{ Form::label('body') }}
{{ Form::textarea('body', Input::old('body', $post->exists ? $post->body : null), array('class' => 'form-control')) }}
</div>
<div class="form-group">
{{ Form::submit('Save', array('class' => 'btn btn-success')) }}
</div>
{{ Form::close() }}
</div>
@stop
workbench/cartalyst/blog/themes/frontend/default/packages/cartalyst/blog/views/index.blade.php
@extends('layouts/default')
{{-- Page title --}}
@section('title')
Blog
@parent
@stop
{{-- Meta description --}}
@section('meta-description')
Cartalyst Blog
@stop
{{-- Page content --}}
@section('content')
<div class="container">
<div class="col-md-12">
<h2 class="text-center">Blog</h2>
@foreach($posts as $post)
<article>
<h3><a href='{{ URL::to("blog/{$post->id}") }}'>{{ $post->title }}</a> <small>{{ $post->created_at }}</small></h3>
<p>{{ $post->summary }}</p>
</article>
@endforeach
<div class="text-center">
{{ $posts->links() }}
</div>
</div>
</div>
@stop
workbench/cartalyst/blog/themes/frontend/default/packages/cartalyst/blog/views/show.blade.php
@extends('layouts/default')
{{-- Page title --}}
@section('title')
Cartalyst Blog
@parent
@stop
{{-- Meta description --}}
@section('meta-description')
Cartalyst Blog
@stop
{{-- Page content --}}
@section('content')
<div class="container">
<div class="col-md-12">
<h2 class="text-center">Blog</h2>
<article>
<h2>{{ $post->title }}</h2>
<p>{{ $post->body }}</p>
</article>
</div>
</div>
@stop
run php artisan theme:publish --extension=cartalyst/blog
Now that we've prepared our files, we can continue and install the extension.
Navigate to your admin dashboard, under Operations choose Extensions,
Click on the edit button next to your extension
Click Install, this will install and run your extensions migrations.
Click Enable.
At this point, you should find a new Blog menu item on the admin dashboard, navigate to it and start creating posts!
On the frontend, you will find a blog menu item as well, navigate to it to find your blog listings.
This package's autoloading happens automatically after generating the migration,
php artisan dump-autoload
is invoked right after the migration is created.
If you do not create any migrations, or you're installing your package from scratch, you have to manually dump-autoload.
You can dump-autoload your workbench package using one of the following methods
run php artisan dump-autoload
This will also run for all of your workbenches.
run composer dump-autoload
This will dump the required files for auto loading.