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

Pagebuilder in a specific controller #8

Closed
aledevil opened this issue May 7, 2020 · 23 comments
Closed

Pagebuilder in a specific controller #8

aledevil opened this issue May 7, 2020 · 23 comments

Comments

@aledevil
Copy link

aledevil commented May 7, 2020

good evening,
I have a project already started and running with Laravel 5.7.
I would like to give my users the possibility to create web pages through this page builder and therefore I would like to integrate this page builder into a specific controller of my project.

I tried to install it with the composer, but I can't edit the files to apply it only to a controller because they all files remain in the vendor folder and are not published in my project

@aledevil aledevil changed the title information Pagebuilder in a specific controller May 7, 2020
@HansSchouten
Copy link
Owner

HansSchouten commented May 7, 2020

Hi, I would suggest you in the pagebuilder.php config file to set use_login, use_website_manager and use_router to false. Now the default PHPageBuilder login area and the frontend routes are disabled. Next you will need to implement your own controller actions for launching the pagebuilder and for serving all created pages. I am planning to make this easier and integrate it into the Laravel-Pagebuilder project, but at the moment this is what I used in another project:

To manage pages

Create a basic table view that shows pages that are stored in a pagebuilder__pages table in your database. Add basic functionality to create/edit/delete a page and a button for each page to launch the pagebuilder.

To launch the pagebuilder

routes\web.php

Route::any('/admin/pages/{id}/build', 'App\Http\Controllers\PageBuilderController@build')->name('pagebuilder.build');
Route::any('/admin/pages/build', 'App\Http\Controllers\PageBuilderController@build');

config\pagebuilder.php

'pagebuilder' => [
	'class' => PHPageBuilder\Modules\GrapesJS\PageBuilder::class,
	'url' => '/admin/pages/build',      // the route you created for your pagebuilder controller
	'actions' => [
		'back' => '/admin/pages'    // URL to a table overview of all pages
	]
],

App\Providers\AppServiceProvider.php boot method

// register singleton phppagebuilder (this ensures all phpb_ helpers have the right config without first manually creating a pagebuilder instance)
$this->app->singleton('phpPageBuilder', function($app) {
    return new PHPageBuilder(config('pagebuilder'));
});
$this->app->make('phpPageBuilder');

resources\views\pagebuilder\scripts.blade.php

<script type="text/javascript">
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': '{{ csrf_token() }}'
        }
    });

    window.customConfig = {
        assetManager: {
            headers: {
                'X-CSRF-TOKEN': '{{ csrf_token() }}'
            }
        }
    };
</script>

App\Http\Controllers\PageBuilderController.php

/**
 * Edit the given page with the page builder.
 *
 * @param int|null $pageId
 * @throws Throwable
 */
public function build($pageId = null)
{
    $route = $_GET['route'] ?? null;
    $action = $_GET['action'] ?? null;
    $pageId = is_numeric($pageId) ? $pageId : ($_GET['page'] ?? null);
    $pageRepository = new \PHPageBuilder\Repositories\PageRepository;
    $page = $pageRepository->findWithId($pageId);

    $phpPageBuilder = app()->make('phpPageBuilder');
    $pageBuilder = $phpPageBuilder->getPageBuilder();

    $customScripts = view("pagebuilder.scripts")->render();
    $pageBuilder->customScripts('head', $customScripts);

    $pageBuilder->handleRequest($route, $action, $page);
}

To publicly serve all pages

routes\web.php

Add this at the bottom of your routes file

Route::any('{uri}', [
    'uses' => 'App\Http\Controllers\WebsiteController@uri',
    'as' => 'page',
])->where('uri', '.*');

App\Http\Controllers\WebsiteController.php

/**
 * Show the website page that corresponds with the current URI.
 */
public function uri()
{
    $pageBuilder = app()->make('phpPageBuilder');
    $pageBuilder->handlePublicRequest();
}

@HansSchouten HansSchouten pinned this issue May 7, 2020
@aledevil
Copy link
Author

aledevil commented May 8, 2020

Hello there, thank you very much for your help
i've setup all page for index/create/delete my pages
i've setup the "edit" button that call your build function but i got always this error

Error
"Argument 3 passed to PHPageBuilder\Modules\GrapesJS\PageBuilder::handleRequest() must implement interface PHPageBuilder\Contracts\PageContract or be null, instance of App\PageBuilder given, called in C:\xampp\htdocs\crmhotel\app\Http\Controllers\PageBuilderController.php on line 166 "

This my function build
` /**
* Edit the given page with the page builder.
*
* @param int|null $pageId
* @throws Throwable
* @throws \Throwable
*/
public function build($pageId = null)
{
$pageId = is_numeric($pageId) ? $pageId : ($_GET['page'] ?? null);
$page = PageBuilder::find($pageId);
$route = $_GET['route'] ?? null;
$action = $_GET['action'] ?? null;

    $phpPageBuilder = app()->make('phpPageBuilder');
    $pageBuilder = $phpPageBuilder->getPageBuilder();

    $customScripts = view("pagebuilder.scripts")->render();
    $pageBuilder->customScripts('head', $customScripts);

    $pageBuilder->handleRequest($route, $action, $page);
}

`
the variable $page call the method PageBuilder, it's correct? where i'm doing wrong?

This is my model
class PageBuilder extends Model { protected $table = "pagebuilder_pages"; protected $fillable = ['name', 'layout', 'data']; }

@HansSchouten
Copy link
Owner

HansSchouten commented May 8, 2020

$pageBuilder->handleRequest($route, $action, $page); expects the $page argument to implement the PHPageBuilder\Contracts\PageContract to ensure all methods that the pagebuilder will call are present on the Page instance. So it should not be your created eloquent model, but a PHPageBuilder\Page instance (with the same id as your eloquent model instance would have). In the code I gave I did not explain where my $page came from, so I will update that in a minute to make my snippet complete. It should be:

$pageRepository = new \PHPageBuilder\Repositories\PageRepository;
$page = $pageRepository->findWithId($pageId);

@aledevil
Copy link
Author

aledevil commented May 8, 2020

Ok perfetct!
i add this function to my controller

public function page($pageId = null) { $pageRepository = new \PHPageBuilder\Repositories\PageRepository; $page = $pageRepository->findWithId($pageId); return $page; }

now if i call the url "/pagebuilder/1/build" (1 is id of my page), i got the loader, but it keeps spinning forever

another question:
when i create a new page, i add a row in db in table pagebuilder_pages with name and data, what i have to pass to "layout"? (using demo theme)
i have to add a row in pagebuilder_page_translations with page id, locale, title and route?
thank you again

@HansSchouten
Copy link
Owner

HansSchouten commented May 8, 2020

A layout is a default html structure in which all your page blocks will be loaded. The layouts are stored in the themes\[theme-name]\layouts folder. I added a default "master" layout which just includes the default html structure with all style and script tags. But you could also create for example a "header-footer" layout which also includes a header and footer by default to any of your pages that have this layout. So the layout field of a page should be the name of the folder in which you store your layout's view.php file.

You indeed need to also have a record in the pagebuilder__page_translations table, with the page id, the locale (probably en) and the route (which is the URL you access that page on in that language). Hopefully that will solve the spinner issue.

@aledevil
Copy link
Author

aledevil commented May 8, 2020

now miss the assets
i got an error in console log for "/assets/pagebuilder/page-injections.js:1"
with "Uncaught ReferenceError: $ is not defined" at Object.15 and Object.16

if i try to open "/assets/pagebuilder/grapesjs-touch.min.js.map"
i got "Asset not found"

@HansSchouten
Copy link
Owner

I know that error and have fixed it in the PHPageBuilder project. For now can you try a different browser than Chrome or do an extra page reload if the error occurs? I will soon create a new release.

@aledevil
Copy link
Author

aledevil commented May 8, 2020

the error of asset not found disappear, thank you

but got alway this
page-injection.js:1
Uncaught ReferenceError: $ is not defined
at Object.16 (page-injection.js:1)
at e (page-injection.js:1)
at Object.15 (page-injection.js:1)
at e (page-injection.js:1)
at page-injection.js:1
at page-injection.js:1
and loading pagebuilder never stopped

@HansSchouten
Copy link
Owner

I just made a v0.10.1 release. Could try a composer update and see if the latest PHPageBuilder solves the issue.

@aledevil
Copy link
Author

aledevil commented May 8, 2020

yep! now works!
thank you very much for your help

@HansSchouten
Copy link
Owner

Great! You're welcome

@aledevil
Copy link
Author

aledevil commented May 8, 2020

this is not a issue, but a request

there is a way to include a plugin of grapejs?
for example if i want to include the plugin: gjs-preset-webpage
how i can do? i have to create all blocks?

@HansSchouten
Copy link
Owner

HansSchouten commented May 8, 2020

The way grapesjs-blocks-basic as part of gjs-preset-webpage is created it takes a very long time to create custom blocks (it is fully JS instead of just a piece of html in a file) and it is next to impossible to easily augment it with dynamic functionality (PHP that adds additional values and html structure), so therefore PHPageBuilder works completely different without any user supplied JS. Imagine you would be writing this for each of your blocks. It takes a lot of effort to build it and to learn how the syntax works. As this project has a heavily customized version of GrapesJS, unfortunately we cannot use the basic blocks of GrapesJS.

However, in this project each block has just a simple .html or a .php file and that's it. Creating blocks is now just a matter of tearing an awesome HTML5 theme apart into small snipets (i.e. blocks) and you're done.

That being said, I can imagine that is still not always pleasant to do this for each new website so I am planning to create a default theme based on bootstrap that has blocks for each bootstrap component.

@aledevil
Copy link
Author

aledevil commented May 8, 2020

That being said, I can imagine that is still not always pleasant to do this for each new website so I am planning to create a default theme based on bootstrap that has blocks for each bootstrap component.

that would be really cool! if I can help you let me know
I'll start by creating theme that i need and then I'll show you if you want
thank you very much again for your help

@HansSchouten
Copy link
Owner

HansSchouten commented May 8, 2020

Awesome! It would be cool to have some example material somewhere, for others to quickly get started. The bootstrap theme is getting there, as well as better documentation, but at the moment I was still busy improving the system and build it while directly using it for some projects.

For reference, this is what I recently quickly build: https://www.gambiabirdingtours.com using PHPageBuilder and the boilerplate (not even Laravel), based on this theme. It was really just cutting up the template, create the pages with the desired blocks, add texts, improve styling and done. I was thinking about sharing the code, but it uses a paid template so I guess I just have to do a bootstrap version in the near future.

What I can share already, is an example of the theme structure I used:
afbeelding

@aledevil
Copy link
Author

aledevil commented May 8, 2020

where i can edit the icon of blocks?
image

and there is a way to create another group like "General"?
thank you

@HansSchouten
Copy link
Owner

HansSchouten commented May 8, 2020

I use a cronjob to automatically take screenshots of the rendered blocks once a block has changed: https://github.com/HansSchouten/PHPageBuilder-Laravel-Screenshots. Each file contains the segment that should be added into your own project and you should run composer require spatie/browsershot.

To assign a block to another group, create a config.php in the folder of your block and add the following:

<?php
return [
    'category' => 'Group name',
];

@aledevil
Copy link
Author

aledevil commented May 8, 2020

i'm still tring to create some block, but some block created with view.html can't be edited in page builder
for example if i create a block "link" with insile view.html only the some text this have setting and can be edited in pagebuilder
but if i create a block input with label, the label can't be edit in pagebuilder

could you say why this? thank you

@HansSchouten
Copy link
Owner

HansSchouten commented May 8, 2020

That is correct, at the moment I did not create a sidebar settings for the input placeholder attributes, but I did create settings for a Link. So that explains this behaviour, this will be further extended.

Or do you mean an actual <label></label> is not text editable?

@aledevil
Copy link
Author

aledevil commented May 8, 2020

i create a block like this
<div class="form-group"><label for="text">Label input</label><input type="text" class="form-control" id="text" name="text" placeholder="Placeholder" /></div>

and the text "label input" is not editable

if i put text on a p tag is editable

@HansSchouten
Copy link
Owner

Ah ok, that is an obvious bug, I will make it editable in the next release. About the placeholder I was already aware that it still had to be implemented.

@vladdivotek
Copy link

When I click the "View" button, a blank page opens. Please help
Снимок экрана от 2021-12-10 12-54-01
Снимок экрана от 2021-12-10 12-54-30

.

@annus97
Copy link

annus97 commented Nov 22, 2022

Hi,

I have updated the grapesjs version from 0.15.9 provided in the package to 0.17.27 by updating the import of CDN in the package due to the unavailability of many events in older grapesjs version. After updating the version I am getting error in the app.js file which is in the public/assets/pagebuilder folder, the same file which is in the dist folder of phpagebuilder package. The error is "Uncaught TypeError: Cannot read properties of null (reading 'attributes')". It occurs in other basic functionalities like changing button text or uploading image. The component is removed so accessing its attribute property is giving the error.
Is there any way to generate this app.js file for the latest version of grapesjs or any other proper way to update grapesjs version? Your feedback in this regard will be highly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants