Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unique pages #61

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,28 @@ php artisan migrate
1. Go to **yourapp/admin/page** and see how it works.
2. Define your own templates in app/PageTemplates.php using the Backpack\CRUD API.

## Unique pages usage

Unique pages are pages that exist only once. You can not create a second instance nor delete the current one.

**Only editing**

Each unique page is defined like a page template in app/UniquePages.php using the backpack\CRUD API.
It will be available for editing in the backend at
`< route_prefix >/unique/< page_function_slug >`

For users to access the editing page for the page `about_us` you could add a menu item like so
(remember the url will use the slug of your function):

```html
<li><a href="{{ url(config('backpack.base.route_prefix').'/unique/about-us') }}"><i class="fa fa-file-o"></i> <span>Pages</span></a></li>
```

**Unique pages can easily use revisions**

Be sure to subclass `Backpack\PageManager\app\Models\Page` and follow the docs on setting up revisions for your CRUD.
After that just set the config value `unique_page_revisions` to `true`and you are ready to go.

## Example front-end

No front-end is provided (Backpack only takes care of the admin panel), but for most projects this front-end code will be all you need:
Expand Down
2 changes: 2 additions & 0 deletions src/PageManagerServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public function boot()
$this->publishes([__DIR__.'/resources/views' => base_path('resources/views')], 'views');
// publish PageTemplates trait
$this->publishes([__DIR__.'/app/PageTemplates.php' => app_path('PageTemplates.php')], 'trait');
// publish UniquePages trait
$this->publishes([__DIR__.'/app/UniquePages.php' => app_path('UniquePages.php')], 'trait');
// publish migrations
$this->publishes([__DIR__.'/database/migrations' => database_path('migrations')], 'migrations');
// public config
Expand Down
24 changes: 7 additions & 17 deletions src/app/Http/Controllers/Admin/PageCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@

use App\PageTemplates;
// VALIDATION: change the requests to match your own file names if you need form validation
use Backpack\PageManager\app\TraitReflections;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\PageManager\app\Http\Requests\PageRequest as StoreRequest;
use Backpack\PageManager\app\Http\Requests\PageRequest as UpdateRequest;

class PageCrudController extends CrudController
{
use PageTemplates;
use TraitReflections;

public function setup($template_name = false)
{
parent::__construct();

$modelClass = config('backpack.pagemanager.page_model_class', 'Backpack\PageManager\app\Models\Page');

$this->checkForTemplatesAndUniquePagesNotDistinct();

/*
|--------------------------------------------------------------------------
| BASIC CRUD INFORMATION
Expand All @@ -27,6 +31,9 @@ public function setup($template_name = false)
$this->crud->setRoute(config('backpack.base.route_prefix').'/page');
$this->crud->setEntityNameStrings(trans('backpack::pagemanager.page'), trans('backpack::pagemanager.pages'));

$template_names = $this->getTemplateNames();
$this->crud->addClause('whereIn', 'template', $template_names);

/*
|--------------------------------------------------------------------------
| COLUMNS
Expand Down Expand Up @@ -179,23 +186,6 @@ public function useTemplate($template_name = false)
}
}

/**
* Get all defined templates.
*/
public function getTemplates($template_name = false)
{
$templates_array = [];

$templates_trait = new \ReflectionClass('App\PageTemplates');
$templates = $templates_trait->getMethods(\ReflectionMethod::IS_PRIVATE);

if (! count($templates)) {
abort(503, trans('backpack::pagemanager.template_not_found'));
}

return $templates;
}

/**
* Get all defined template as an array.
*
Expand Down
247 changes: 247 additions & 0 deletions src/app/Http/Controllers/Admin/UniquePageCrudController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
<?php

namespace Backpack\PageManager\app\Http\Controllers\Admin;

use App\UniquePages;
use Illuminate\Http\Request;
use Backpack\PageManager\app\TraitReflections;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Http\Controllers\CrudFeatures\SaveActions;

class UniquePageCrudController extends CrudController
{
use SaveActions;
use UniquePages;
use TraitReflections;

public function setup()
{
parent::setup();

$modelClass = config('backpack.pagemanager.unique_page_model_class', 'Backpack\PageManager\app\Models\Page');

$this->checkForTemplatesAndUniquePagesNotDistinct();

/*
|--------------------------------------------------------------------------
| BASIC CRUD INFORMATION
|--------------------------------------------------------------------------
*/
$this->crud->setModel($modelClass);
// Don't set route or entity names here. These depend on the page you are editing

$this->crud->denyAccess(['list', 'create', 'delete']);

if (config('backpack.pagemanager.unique_page_revisions')) {
$this->crud->allowAccess('revisions');
}
}

/**
* Edit the unique page retrieved by slug.
*
* @param string $slug
* @return Response
*/
public function uniqueEdit($slug)
{
$model = $this->crud->model;
$entry = $model::findBySlug($slug);

if (! $entry) {
$entry = $this->createMissingPage($slug);
}

$this->uniqueSetup($entry);

return parent::edit($entry->id);
}

/**
* Update the unique page.
*
* @param string $slug
* @param int $id
* @return \Illuminate\Http\RedirectResponse
*/
public function update($slug, $id)
{
$model = $this->crud->model;
$entry = $model::findBySlugOrFail($slug);

$this->uniqueSetup($entry);

return parent::updateCrud();
}

/**
* Set the crud route.
*
* @param $slug
*/
public function setRoute($slug)
{
$this->crud->setRoute(config('backpack.base.route_prefix').'/unique/'.$slug);
}

/**
* Populate the update form with basic fields that all pages need.
*
* @param Model $page
*/
public function addDefaultPageFields($page)
{
$fields = [
[
'name' => 'buttons',
'type' => 'custom_html',
'value' => $this->buttons($page),
],
[
'name' => 'template',
'type' => 'hidden',
],
[
'name' => 'name',
],
[
'name' => 'title',
],
[
'name' => 'slug',
'type' => 'hidden',
],
];

$this->crud->addFields($fields);
}

/**
* Build the buttons html for the edit form.
*
* @param Model $page
* @return string
*/
public function buttons($page)
{
$openButton = $page->getOpenButton();
$revisionsButton = view('crud::buttons.revisions', ['crud' => $this->crud, 'entry' => $page]);

return $openButton.' '.$revisionsButton;
}

/**
* Create missing unique page by slug.
*
* @param $slug
* @return mixed
*/
public function createMissingPage($slug)
{
$slugs = $this->getUniqueSlugs();

if (! $slugs->has($slug)) {
abort(404);
}

$page = $slugs->pull($slug);
$model = $this->crud->model;

return $model::create([
'template' => $page,
'name' => camel_case($page),
'title' => camel_case($page),
'slug' => $slug,
]);
}

/**
* Display the revisions for specified resource.
*
* @param $slug
* @param $id
* @return Response
*/
public function uniqueRevisions($slug, $id)
{
$model = $this->crud->model;
$entry = $model::findBySlugOrFail($slug);

$this->uniqueSetup($entry);

return parent::listRevisions($entry->id);
}

/**
* Restore a specific revision for the specified resource.
*
* Used via AJAX in the revisions view
*
* @param string $slug
* @param int $id
*
* @return JSON Response containing the new revision that was created from the update
* @return HTTP 500 if the request did not contain the revision ID
*/
public function restoreUniqueRevision($slug, $id)
{
$model = $this->crud->model;
$entry = $model::findBySlugOrFail($slug);

$this->uniqueSetup($entry);

return parent::restoreRevision($id);
}

/**
* Setup the controller for the entry.
*
* @param $entry
*/
protected function uniqueSetup($entry)
{
$this->crud->entry = $entry;

$this->setRoute($entry->slug);

$this->addDefaultPageFields($entry);
$this->crud->setEntityNameStrings($this->crud->makeLabel($entry->template), $this->crud->makeLabel($entry->template));

$this->{$entry->template}();
}

/*
|--------------------------------------------------------------------------
| SaveActions overrides
|--------------------------------------------------------------------------
*/

/**
* Overrides trait version to remove 'save_and_back' and 'save_and_new'.
*
* @return [type] [description]
*/
public function getSaveAction()
{
$saveCurrent = [
'value' => $this->getSaveActionButtonName('save_and_back'),
'label' => $this->getSaveActionButtonName('save_and_back'),
];

return [
'active' => $saveCurrent,
'options' => [],
];
}

/**
* Override trait version to not update the session variable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have no "save actions" here and overwrite with save_and_back.
This would geht default for this session in all Crud-Views.
As we don't want to overwrite behaviour when user can't choose, we need this (empty) implementation

Copy link
Contributor Author

@OliverZiegler OliverZiegler Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added some more comment to make this clear ;)

* This way we preserve the user chosen save action and don't overwrite with.
*
* @param [type] $forceSaveAction [description]
*/
public function setSaveAction($forceSaveAction = null)
{
// do nothing to preserve session value for other crud
}
}
10 changes: 0 additions & 10 deletions src/app/PageTemplates.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,4 @@ private function services()
'placeholder' => trans('backpack::pagemanager.content_placeholder'),
]);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to be part of the PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just moved about_us to the UniquePages trait.

As these traits get published and need to be edited by developers, this serves as an example how to define your templates/uniquePages.


private function about_us()
{
$this->crud->addField([
'name' => 'content',
'label' => trans('backpack::pagemanager.content'),
'type' => 'wysiwyg',
'placeholder' => trans('backpack::pagemanager.content_placeholder'),
]);
}
}
Loading