Skip to content
New issue

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

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

Already on GitHub? # to your account

feat: allow custom output via formatters #483

Merged
merged 13 commits into from
Mar 4, 2022
31 changes: 12 additions & 19 deletions src/BladeRouteGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,37 @@

namespace Tightenco\Ziggy;

use Tightenco\Ziggy\Output\MergeScript;
use Tightenco\Ziggy\Output\Script;

class BladeRouteGenerator
{
public static $generated;

public function generate($group = null, $nonce = null)
{
$payload = new Ziggy($group);
$ziggy = new Ziggy($group);

$nonce = $nonce ? ' nonce="' . $nonce . '"' : '';

if (static::$generated) {
return $this->generateMergeJavascript(json_encode($payload->toArray()['routes']), $nonce);
return (string) $this->generateMergeJavascript($ziggy, $nonce);
}

$routeFunction = $this->getRouteFunction();
$function = $this->getRouteFunction();

static::$generated = true;

return <<<HTML
<script type="text/javascript"{$nonce}>
const Ziggy = {$payload->toJson()};
$output = config('ziggy.output.script', Script::class);

$routeFunction
</script>
HTML;
return (string) new $output($ziggy, $function, $nonce);
}

private function generateMergeJavascript($json, $nonce)
private function generateMergeJavascript(Ziggy $ziggy, $nonce)
{
return <<<HTML
<script type="text/javascript"{$nonce}>
(function () {
const routes = {$json};

Object.assign(Ziggy.routes, routes);
})();
</script>
HTML;
$output = config('ziggy.output.merge_script', MergeScript::class);

return new $output($ziggy, $nonce);
}

private function getRouteFilePath()
Expand Down
14 changes: 4 additions & 10 deletions src/CommandRouteGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Tightenco\Ziggy\Output\File;
use Tightenco\Ziggy\Ziggy;

class CommandRouteGenerator extends Command
Expand Down Expand Up @@ -37,18 +38,11 @@ public function handle()

private function generate($group = false)
{
$payload = (new Ziggy($group, $this->option('url') ? url($this->option('url')) : null))->toJson();
$ziggy = (new Ziggy($group, $this->option('url') ? url($this->option('url')) : null));

return <<<JAVASCRIPT
const Ziggy = {$payload};
$output = config('ziggy.output.file', File::class);

if (typeof window !== 'undefined' && typeof window.Ziggy !== 'undefined') {
Object.assign(Ziggy.routes, window.Ziggy.routes);
}

export { Ziggy };

JAVASCRIPT;
return (string) new $output($ziggy);
}

protected function makeDirectory($path)
Expand Down
30 changes: 30 additions & 0 deletions src/Output/File.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Tightenco\Ziggy\Output;

use Stringable;
use Tightenco\Ziggy\Ziggy;

class File implements Stringable
{
protected $ziggy;

public function __construct(Ziggy $ziggy)
{
$this->ziggy = $ziggy;
}

public function __toString(): string
{
return <<<JAVASCRIPT
const Ziggy = {$this->ziggy->toJson()};

if (typeof window !== 'undefined' && typeof window.Ziggy !== 'undefined') {
Object.assign(Ziggy.routes, window.Ziggy.routes);
}

export { Ziggy };

JAVASCRIPT;
}
}
33 changes: 33 additions & 0 deletions src/Output/MergeScript.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Tightenco\Ziggy\Output;

use Stringable;
use Tightenco\Ziggy\Ziggy;

class MergeScript implements Stringable
{
protected $ziggy;
protected $nonce;

public function __construct(Ziggy $ziggy, string $nonce = '')
{
$this->ziggy = $ziggy;
$this->nonce = $nonce;
}

public function __toString(): string
{
$routes = json_encode($this->ziggy->toArray()['routes']);

return <<<HTML
<script type="text/javascript"{$this->nonce}>
(function () {
const routes = {$routes};

Object.assign(Ziggy.routes, routes);
})();
</script>
HTML;
}
}
31 changes: 31 additions & 0 deletions src/Output/Script.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Tightenco\Ziggy\Output;

use Stringable;
use Tightenco\Ziggy\Ziggy;

class Script implements Stringable
{
protected $ziggy;
protected $function;
protected $nonce;

public function __construct(Ziggy $ziggy, string $function, string $nonce = '')
{
$this->ziggy = $ziggy;
$this->function = $function;
$this->nonce = $nonce;
}

public function __toString(): string
{
return <<<HTML
<script type="text/javascript"{$this->nonce}>
const Ziggy = {$this->ziggy->toJson()};

{$this->function}
</script>
HTML;
}
}
36 changes: 36 additions & 0 deletions tests/Unit/CommandRouteGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\URL;
use Tests\TestCase;
use Tightenco\Ziggy\Output\File;

class CommandRouteGeneratorTest extends TestCase
{
Expand Down Expand Up @@ -92,6 +93,28 @@ public function can_generate_file_with_config_applied()
$this->assertFileEquals('./tests/fixtures/ziggy.js', base_path('resources/js/ziggy.js'));
}

/** @test */
public function can_generate_file_with_custom_output_formatter()
{
config([
'ziggy' => [
'except' => ['admin.*'],
'output' => [
'file' => CustomFileFormatter::class,
],
],
]);

$router = app('router');
$router->get('posts/{post}/comments', $this->noop())->name('postComments.index');
$router->get('admin', $this->noop())->name('admin.dashboard'); // Excluded, should NOT be present in file
$router->getRoutes()->refreshNameLookups();

Artisan::call('ziggy:generate');

$this->assertFileEquals('./tests/fixtures/ziggy-custom.js', base_path('resources/js/ziggy.js'));
}

/** @test */
public function can_generate_file_for_specific_configured_route_group()
{
Expand All @@ -109,3 +132,16 @@ public function can_generate_file_for_specific_configured_route_group()
$this->assertFileEquals('./tests/fixtures/admin.js', base_path('resources/js/admin.js'));
}
}

class CustomFileFormatter extends File
{
public function __toString(): string
{
return <<<JAVASCRIPT
// This is a custom template
const Ziggy = {$this->ziggy->toJson()};
export { Ziggy };

JAVASCRIPT;
}
}
3 changes: 3 additions & 0 deletions tests/fixtures/ziggy-custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This is a custom template
const Ziggy = {"url":"http:\/\/ziggy.dev","port":null,"defaults":{},"routes":{"postComments.index":{"uri":"posts\/{post}\/comments","methods":["GET","HEAD"]}}};
export { Ziggy };