Skip to content

Commit 69e5ba3

Browse files
authored
Merge pull request #664 from hydephp/refactor-view-publishers
Refactor publishable templates
2 parents f4f5f57 + 019eda7 commit 69e5ba3

File tree

9 files changed

+282
-134
lines changed

9 files changed

+282
-134
lines changed

packages/framework/src/Console/Commands/PublishHomepageCommand.php

+40-44
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44

55
namespace Hyde\Console\Commands;
66

7-
use Hyde\Framework\Actions\PublishesHomepageView;
7+
use Hyde\Console\Concerns\AsksToRebuildSite;
8+
use Hyde\Framework\Features\Templates\Homepages;
9+
use Hyde\Framework\Features\Templates\PublishableContract;
810
use Hyde\Framework\Services\ChecksumService;
911
use Hyde\Hyde;
10-
use Illuminate\Support\Facades\Artisan;
12+
use Illuminate\Support\Collection;
1113
use LaravelZero\Framework\Commands\Command;
1214

1315
/**
@@ -17,94 +19,88 @@
1719
*/
1820
class PublishHomepageCommand extends Command
1921
{
22+
use AsksToRebuildSite;
23+
2024
/** @var string */
2125
protected $signature = 'publish:homepage {homepage? : The name of the page to publish}
2226
{--force : Overwrite any existing files}';
2327

2428
/** @var string */
2529
protected $description = 'Publish one of the default homepages to index.blade.php.';
2630

27-
protected string $selected;
28-
2931
public function handle(): int
3032
{
31-
$this->selected = $this->argument('homepage') ?? $this->promptForHomepage();
33+
$selected = $this->parseSelection();
3234

33-
if (! $this->canExistingIndexFileBeOverwritten()) {
34-
$this->error('A modified index.blade.php file already exists. Use --force to overwrite.');
35+
if (! Homepages::exists($selected)) {
36+
$this->error("Homepage $selected does not exist.");
3537

36-
return 409;
38+
return 404;
3739
}
3840

39-
$returnValue = (new PublishesHomepageView(
40-
$this->selected
41-
))->execute();
42-
43-
if (is_numeric($returnValue)) {
44-
if ($returnValue == 404) {
45-
$this->error('Homepage '.$this->selected.' does not exist.');
41+
if (! $this->canExistingFileBeOverwritten()) {
42+
$this->error('A modified index.blade.php file already exists. Use --force to overwrite.');
4643

47-
return 404;
48-
}
44+
return 409;
4945
}
5046

51-
$this->line("<info>Published page</info> [<comment>$this->selected</comment>]");
47+
Homepages::get($selected)->publish(true);
48+
49+
$this->line("<info>Published page</info> [<comment>$selected</comment>]");
5250

5351
$this->askToRebuildSite();
5452

5553
return Command::SUCCESS;
5654
}
5755

56+
protected function parseSelection(): string
57+
{
58+
return $this->argument('homepage') ?? $this->parseChoiceIntoKey($this->promptForHomepage());
59+
}
60+
5861
protected function promptForHomepage(): string
5962
{
60-
/** @var string $choice */
61-
$choice = $this->choice(
63+
return $this->choice(
6264
'Which homepage do you want to publish?',
6365
$this->formatPublishableChoices(),
6466
0
6567
);
66-
67-
return $this->parseChoiceIntoKey($choice);
6868
}
6969

7070
protected function formatPublishableChoices(): array
7171
{
72-
$keys = [];
73-
foreach (PublishesHomepageView::$homePages as $key => $value) {
74-
$keys[] = "<comment>$key</comment>: {$value['description']}";
75-
}
72+
return $this->getTemplateOptions()->map(function (array $option, string $key): string {
73+
return "<comment>$key</comment>: {$option['description']}";
74+
})->values()->toArray();
75+
}
7676

77-
return $keys;
77+
protected function getTemplateOptions(): Collection
78+
{
79+
return Homepages::options()->map(fn (PublishableContract $page): array => $page::toArray());
7880
}
7981

8082
protected function parseChoiceIntoKey(string $choice): string
8183
{
8284
return strstr(str_replace(['<comment>', '</comment>'], '', $choice), ':', true);
8385
}
8486

85-
protected function canExistingIndexFileBeOverwritten(): bool
87+
protected function canExistingFileBeOverwritten(): bool
8688
{
87-
if (! file_exists(Hyde::getBladePagePath('index.blade.php')) || $this->option('force')) {
89+
if ($this->option('force')) {
8890
return true;
8991
}
9092

91-
return ChecksumService::checksumMatchesAny(ChecksumService::unixsumFile(
92-
Hyde::getBladePagePath('index.blade.php')
93-
)) || $this->option('force');
93+
if (! file_exists(Hyde::getBladePagePath('index.blade.php'))) {
94+
return true;
95+
}
96+
97+
return $this->isTheExistingFileADefaultOne();
9498
}
9599

96-
protected function askToRebuildSite(): void
100+
protected function isTheExistingFileADefaultOne(): bool
97101
{
98-
if ($this->option('no-interaction')) {
99-
return;
100-
}
101-
102-
if ($this->confirm('Would you like to rebuild the site?', 'Yes')) {
103-
$this->line('Okay, building site!');
104-
Artisan::call('build');
105-
$this->info('Site is built!');
106-
} else {
107-
$this->line('Okay, you can always run the build later!');
108-
}
102+
return ChecksumService::checksumMatchesAny(ChecksumService::unixsumFile(
103+
Hyde::getBladePagePath('index.blade.php')
104+
));
109105
}
110106
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hyde\Console\Concerns;
6+
7+
use Illuminate\Support\Facades\Artisan;
8+
9+
trait AsksToRebuildSite
10+
{
11+
protected function askToRebuildSite(): void
12+
{
13+
if ($this->option('no-interaction')) {
14+
return;
15+
}
16+
17+
if ($this->confirm('Would you like to rebuild the site?', 'Yes')) {
18+
$this->line('Okay, building site!');
19+
Artisan::call('build');
20+
$this->info('Site is built!');
21+
} else {
22+
$this->line('Okay, you can always run the build later!');
23+
}
24+
}
25+
}

packages/framework/src/Framework/Actions/PublishesHomepageView.php

-52
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hyde\Framework\Features\Templates;
6+
7+
use Illuminate\Support\Collection;
8+
9+
/** @internal */
10+
final class Homepages
11+
{
12+
public static function options(): Collection
13+
{
14+
return new Collection([
15+
'welcome' => self::welcome(),
16+
'posts' => self::posts(),
17+
'blank' => self::blank(),
18+
]);
19+
}
20+
21+
public static function exists(string $page): bool
22+
{
23+
return self::options()->has($page);
24+
}
25+
26+
public static function get(string $page): ?PublishableContract
27+
{
28+
return self::options()->get($page);
29+
}
30+
31+
public static function welcome(): PublishableContract
32+
{
33+
return new class extends PublishableView
34+
{
35+
protected static string $title = 'Welcome';
36+
protected static string $desc = 'The default welcome page.';
37+
protected static string $path = 'resources/views/homepages/welcome.blade.php';
38+
protected static ?string $outputPath = 'index.blade.php';
39+
};
40+
}
41+
42+
public static function posts(): PublishableContract
43+
{
44+
return new class extends PublishableView
45+
{
46+
protected static string $title = 'Posts Feed';
47+
protected static string $desc = 'A feed of your latest posts. Perfect for a blog site!';
48+
protected static string $path = 'resources/views/homepages/post-feed.blade.php';
49+
protected static ?string $outputPath = 'index.blade.php';
50+
};
51+
}
52+
53+
public static function blank(): PublishableContract
54+
{
55+
return new class extends PublishableView
56+
{
57+
protected static string $title = 'Blank Starter';
58+
protected static string $desc = 'A blank Blade template with just the base layout.';
59+
protected static string $path = 'resources/views/homepages/blank.blade.php';
60+
protected static ?string $outputPath = 'index.blade.php';
61+
};
62+
}
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hyde\Framework\Features\Templates;
6+
7+
interface PublishableContract
8+
{
9+
public static function publish(bool $force = false): bool;
10+
11+
public static function getTitle(): string;
12+
13+
public static function getDescription(): string;
14+
15+
public static function getOutputPath(): string;
16+
17+
public static function toArray(): array;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hyde\Framework\Features\Templates;
6+
7+
use Hyde\Hyde;
8+
9+
abstract class PublishableView implements PublishableContract
10+
{
11+
protected static string $title;
12+
protected static string $desc;
13+
protected static string $path;
14+
protected static ?string $outputPath;
15+
16+
public static function publish(bool $force = false): bool
17+
{
18+
$path = static::getOutputPath();
19+
20+
if (file_exists($path) && ! $force) {
21+
return false;
22+
}
23+
24+
return copy(static::getSourcePath(), $path);
25+
}
26+
27+
public static function getTitle(): string
28+
{
29+
return static::$title;
30+
}
31+
32+
public static function getDescription(): string
33+
{
34+
return static::$desc;
35+
}
36+
37+
public static function getOutputPath(): string
38+
{
39+
// All publishable views at this time are Blade templates so to
40+
// reduce premature complexity we just use the Blade paths here.
41+
42+
return Hyde::getBladePagePath(static::$outputPath ?? static::$path);
43+
}
44+
45+
protected static function getSourcePath(): string
46+
{
47+
return Hyde::vendorPath(static::$path);
48+
}
49+
50+
public static function toArray(): array
51+
{
52+
return [
53+
'name' => static::getTitle(),
54+
'description' => static::getDescription(),
55+
];
56+
}
57+
}

0 commit comments

Comments
 (0)