show-or-create for pages#5115
Conversation
|
Thanks for offering this @cod3monk, but I'm really not keen on maintaining & supporting new endpoints that are built/intended for specific external business processes. These kinds of additions would be a good use case of using the logical theme system to add your own endpoints as somewhat reflected here, which would allow you to add these custom endpoints to your own instance without altering core app code. |
|
Would you be willing to include a I am working on porting the endpoint to the logical theme system, which turns out to be rather tedious. Due to a lack of understanding of the |
No. Here's my take on a port of your changes to a logical theme functions.php
<?php
use BookStack\Entities\Queries\EntityQueries;
use BookStack\Entities\Repos\PageRepo;
use BookStack\Exceptions\NotFoundException;
use BookStack\Facades\Theme;
use BookStack\Http\Controller;
use BookStack\Theming\ThemeEvents;
use Illuminate\Http\Request;
use Illuminate\Routing\Router;
class CustomPageActionsController extends Controller
{
public function __construct(
protected PageRepo $pageRepo,
protected EntityQueries $entityQueries,
) {
}
/**
* If page exists, redirect to show page, otherwise to create page
*/
public function showOrCreate(Request $request, string $bookSlug, string $chapterSlug = null)
{
$data = $this->validate($request, [
'name' => ['required', 'string', 'max:255'],
]);
$pageName = $data['name'];
try {
// Redirect to the page if an existing page is found
$page = $this->entityQueries->pages->findVisibleBySlugsOrFail($bookSlug, $pageName);
return redirect($page->getUrl());
} catch (NotFoundException $e) {
// Otherwise create a new page and start editing it
if ($chapterSlug) {
$parent = $this->entityQueries->chapters->findVisibleBySlugsOrFail($bookSlug, $chapterSlug);
} else {
$parent = $this->entityQueries->books->findVisibleBySlugOrFail($bookSlug);
}
$this->checkOwnablePermission('page-create', $parent);
$page = $this->pageRepo->getNewDraftPage($parent);
$this->pageRepo->publishDraft($page, [
'name' => $pageName,
]);
return redirect($page->getUrl('/edit'));
}
}
}
// Register the routes for our custom controller & action
Theme::listen(ThemeEvents::ROUTES_REGISTER_WEB_AUTH, function (Router $router) {
$router->get('/books/{bookSlug}/show-or-create', [CustomPageActionsController::class, 'showOrCreate']);
$router->get('/books/{bookSlug}/chapter/{chapterSlug}/show-or-create', [CustomPageActionsController::class, 'showOrCreate']);
});I've made changes to the method code but the general logic/routes/endpoints/request-data should be the same with the desired overall output. |
|
Thanks! Code-wise I had almost the same, but it was missing some of the |
This PR adds two new routes:
/books/{bookSlug}/show-or-create?name={pageSlug}and/books/{bookSlug}/chapter/{chapterSlug}/show-or-create?name={pageSlug}The concept is, that with these URL a user will either drop into the edit view of a new Page, or -if the page already exists- be redirected to the page itself.
This solves the feature request mentioned in #5099.