Skip to content

Commit 631a2f2

Browse files
authored
Merge pull request #140 from Laravel-Backpack/create-page-command
Command to create a new page
2 parents 4599134 + 280ad5a commit 631a2f2

File tree

5 files changed

+366
-0
lines changed

5 files changed

+366
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?php
2+
3+
namespace Backpack\Generators\Console\Commands;
4+
5+
use Illuminate\Console\GeneratorCommand;
6+
use Illuminate\Support\Str;
7+
8+
class PageBackpackCommand extends GeneratorCommand
9+
{
10+
use \Backpack\CRUD\app\Console\Commands\Traits\PrettyCommandOutput;
11+
12+
/**
13+
* The console command name.
14+
*
15+
* @var string
16+
*/
17+
protected $name = 'backpack:page';
18+
19+
/**
20+
* The name and signature of the console command.
21+
*
22+
* @var string
23+
*/
24+
protected $signature = 'backpack:page {name}
25+
{--view-path=admin : Path for the view, after resources/views/}
26+
{--layout= : Base layout for the page}';
27+
28+
/**
29+
* The console command description.
30+
*
31+
* @var string
32+
*/
33+
protected $description = 'Generate a Backpack Page';
34+
35+
/**
36+
* The type of class being generated.
37+
*
38+
* @var string
39+
*/
40+
protected $type = 'Resource';
41+
42+
/**
43+
* Execute the console command.
44+
*
45+
* @return bool|null
46+
*
47+
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
48+
*/
49+
public function handle()
50+
{
51+
$input = Str::of($this->getNameInput())
52+
->replace('\\', '/')
53+
->replace('.', '/')
54+
->start('/')
55+
->prepend($this->option('view-path'))
56+
->replace('//', '/')
57+
->trim('/');
58+
59+
$name = $input->afterLast('/')->replace('-', '_')->snake();
60+
$path = $input->beforeLast('/');
61+
$filePath = "$path/$name";
62+
$fullpath = $this->getPath($filePath);
63+
$layout = $this->option('layout');
64+
65+
$this->infoBlock("Creating {$name->replace('_', ' ')->title()} page");
66+
67+
$this->progressBlock("Creating view <fg=blue>resources/views/${filePath}.blade.php</>");
68+
69+
// check if the file already exists
70+
if ((! $this->hasOption('force') || ! $this->option('force')) && $this->alreadyExists($filePath)) {
71+
$this->closeProgressBlock('Already existed', 'yellow');
72+
73+
return false;
74+
}
75+
76+
$this->makeDirectory($fullpath);
77+
78+
// create page view
79+
$stub = $this->buildClass($filePath);
80+
$stub = str_replace('layout', $layout, $stub);
81+
$stub = str_replace('Dummy Name', $name->replace('_', ' ')->title(), $stub);
82+
$this->files->put($fullpath, $stub);
83+
84+
$this->closeProgressBlock();
85+
86+
// Clean up name
87+
$name = $name->replace('_', ' ')->replace('-', ' ')->title();
88+
89+
// create controller
90+
$this->call('backpack:page-controller', [
91+
'name' => $name,
92+
'--view-path' => $path,
93+
]);
94+
95+
// create route
96+
$this->call('backpack:add-custom-route', [
97+
'code' => "Route::get('{$name->kebab()}', '{$name->studly()}Controller@index')->name('page.{$name->kebab()}.index');",
98+
]);
99+
100+
// create the sidebar item
101+
$this->call('backpack:add-sidebar-content', [
102+
'code' => "<li class=\"nav-item\"><a class=\"nav-link\" href=\"{{ backpack_url('{$name->kebab()}') }}\"><i class=\"nav-icon la la-question\"></i> {$name}</a></li>",
103+
]);
104+
105+
$url = Str::of(config('app.url'))->finish('/')->append("admin/{$name->kebab()}");
106+
107+
$this->newLine();
108+
$this->note("Page {$name} created.");
109+
$this->note("Go to <fg=blue>$url</> to access your new page.");
110+
$this->newLine();
111+
}
112+
113+
/**
114+
* Get the stub file for the generator.
115+
*
116+
* @return string
117+
*/
118+
protected function getStub()
119+
{
120+
return __DIR__.'/../stubs/page.stub';
121+
}
122+
123+
/**
124+
* Determine if the class already exists.
125+
*
126+
* @param string $name
127+
* @return bool
128+
*/
129+
protected function alreadyExists($name)
130+
{
131+
return $this->files->exists($this->getPath($name));
132+
}
133+
134+
/**
135+
* Get the destination class path.
136+
*
137+
* @param string $name
138+
* @return string
139+
*/
140+
protected function getPath($name)
141+
{
142+
return resource_path("views/$name.blade.php");
143+
}
144+
}
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
<?php
2+
3+
namespace Backpack\Generators\Console\Commands;
4+
5+
use Illuminate\Console\GeneratorCommand;
6+
use Illuminate\Support\Str;
7+
8+
class PageControllerBackpackCommand extends GeneratorCommand
9+
{
10+
use \Backpack\CRUD\app\Console\Commands\Traits\PrettyCommandOutput;
11+
12+
/**
13+
* The console command name.
14+
*
15+
* @var string
16+
*/
17+
protected $name = 'backpack:page-controller';
18+
19+
/**
20+
* The name and signature of the console command.
21+
*
22+
* @var string
23+
*/
24+
protected $signature = 'backpack:page-controller {name} {--view-path=}';
25+
26+
/**
27+
* The console command description.
28+
*
29+
* @var string
30+
*/
31+
protected $description = 'Generate a Backpack PageController';
32+
33+
/**
34+
* The type of class being generated.
35+
*
36+
* @var string
37+
*/
38+
protected $type = 'Controller';
39+
40+
/**
41+
* Execute the console command.
42+
*
43+
* @return bool|null
44+
*
45+
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
46+
*/
47+
public function handle()
48+
{
49+
$name = $this->getNameInput();
50+
$class = $this->qualifyClass($name);
51+
$fullPath = $this->getPath($class);
52+
$path = Str::of($fullPath)->after(base_path())->trim('\\/');
53+
54+
$this->progressBlock("Creating controller <fg=blue>{$path}</>");
55+
56+
if ($this->isReservedName($name)) {
57+
$this->errorProgressBlock();
58+
$this->note("The name '$name' is reserved by PHP.", 'red');
59+
60+
return false;
61+
}
62+
63+
// Next, We will check to see if the class already exists. If it does, we don't want
64+
// to create the class and overwrite the user's code. So, we will bail out so the
65+
// code is untouched. Otherwise, we will continue generating this class' files.
66+
if ((! $this->hasOption('force') ||
67+
! $this->option('force')) &&
68+
$this->alreadyExists($class)) {
69+
$this->closeProgressBlock('Already existed', 'yellow');
70+
71+
return false;
72+
}
73+
74+
// Next, we will generate the path to the location where this class' file should get
75+
// written. Then, we will build the class and make the proper replacements on the
76+
// stub files so that it gets the correctly formatted namespace and class name.
77+
$this->makeDirectory($fullPath);
78+
79+
$this->files->put($fullPath, $this->sortImports($this->buildClass($class)));
80+
81+
$this->closeProgressBlock();
82+
}
83+
84+
/**
85+
* Get the desired class name from the input.
86+
*
87+
* @return string
88+
*/
89+
protected function getNameInput()
90+
{
91+
return Str::of($this->argument('name'))->trim()->studly();
92+
}
93+
94+
/**
95+
* Get the destination class path.
96+
*
97+
* @param string $name
98+
* @return string
99+
*/
100+
protected function getPath($name)
101+
{
102+
return str_replace('.php', 'Controller.php', parent::getPath($name));
103+
}
104+
105+
/**
106+
* Get the stub file for the generator.
107+
*
108+
* @return string
109+
*/
110+
protected function getStub()
111+
{
112+
return __DIR__.'/../stubs/page-controller.stub';
113+
}
114+
115+
/**
116+
* Get the default namespace for the class.
117+
*
118+
* @param string $rootNamespace
119+
* @return string
120+
*/
121+
protected function getDefaultNamespace($rootNamespace)
122+
{
123+
return $rootNamespace.'\Http\Controllers\Admin';
124+
}
125+
126+
/**
127+
* Replace the path name for the given stub.
128+
*
129+
* @param string $stub
130+
* @param string $name
131+
* @return string
132+
*/
133+
protected function replacePathStrings(&$stub)
134+
{
135+
$viewName = $this->getNameInput()->snake('_');
136+
$pathDot = Str::of($this->option('view-path'))
137+
->replace('/', '.')
138+
->replace('\\', '.')
139+
->append('.'.$viewName)
140+
->trim('.');
141+
$pathSlash = $pathDot->replace('.', '/');
142+
143+
$stub = str_replace('dummy.path', $pathDot, $stub);
144+
$stub = str_replace('dummy/path', $pathSlash, $stub);
145+
146+
return $this;
147+
}
148+
149+
/**
150+
* Replace the name for the given stub.
151+
*
152+
* @param string $stub
153+
* @param string $name
154+
* @return string
155+
*/
156+
protected function replaceNameStrings(&$stub)
157+
{
158+
$name = $this->getNameInput();
159+
160+
$stub = str_replace('DummyName', $name, $stub);
161+
$stub = str_replace('dummyName', $name->lcfirst(), $stub);
162+
$stub = str_replace('Dummy Name', $name->kebab()->replace('-', ' ')->title(), $stub);
163+
164+
return $this;
165+
}
166+
167+
/**
168+
* Build the class with the given name.
169+
*
170+
* @param string $name
171+
* @return string
172+
*/
173+
protected function buildClass($name)
174+
{
175+
$stub = $this->files->get($this->getStub());
176+
177+
return $this
178+
->replaceNamespace($stub, $name)
179+
->replacePathStrings($stub)
180+
->replaceNameStrings($stub)
181+
->replaceClass($stub, $name);
182+
}
183+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace DummyNamespace;
4+
5+
use Illuminate\Routing\Controller;
6+
7+
/**
8+
* Class DummyClassController
9+
* @package App\Http\Controllers\Admin
10+
* @property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
11+
*/
12+
class DummyClassController extends Controller
13+
{
14+
public function index()
15+
{
16+
return view('dummy.path', [
17+
'title' => 'Dummy Name',
18+
'breadcrumbs' => [
19+
trans('backpack::crud.admin') => backpack_url('dashboard'),
20+
'DummyName' => false,
21+
],
22+
'page' => 'resources/views/dummy/path.blade.php',
23+
'controller' => 'app/Http/Controllers/Admin/DummyNameController.php',
24+
]);
25+
}
26+
}

src/Console/stubs/page.stub

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@extends(backpack_view('blank'))
2+
3+
@section('content')
4+
<div class="jumbotron">
5+
<h1 class="mb-4">Dummy Name</h1>
6+
7+
<p>Go to <code>{{ $page }}</code> to edit this view or <code>{{ $controller }}</code> to edit the controller.</p>
8+
</div>
9+
@endsection

src/GeneratorsServiceProvider.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use Backpack\Generators\Console\Commands\CrudOperationBackpackCommand;
1313
use Backpack\Generators\Console\Commands\CrudRequestBackpackCommand;
1414
use Backpack\Generators\Console\Commands\ModelBackpackCommand;
15+
use Backpack\Generators\Console\Commands\PageBackpackCommand;
16+
use Backpack\Generators\Console\Commands\PageControllerBackpackCommand;
1517
use Backpack\Generators\Console\Commands\RequestBackpackCommand;
1618
use Backpack\Generators\Console\Commands\ViewBackpackCommand;
1719
use Illuminate\Support\ServiceProvider;
@@ -29,6 +31,8 @@ class GeneratorsServiceProvider extends ServiceProvider
2931
CrudBackpackCommand::class,
3032
ChartBackpackCommand::class,
3133
ModelBackpackCommand::class,
34+
PageBackpackCommand::class,
35+
PageControllerBackpackCommand::class,
3236
RequestBackpackCommand::class,
3337
ViewBackpackCommand::class,
3438
];

0 commit comments

Comments
 (0)