Skip to content
This repository has been archived by the owner on Mar 24, 2020. It is now read-only.

Commit

Permalink
Dynamic lookups (#6)
Browse files Browse the repository at this point in the history
* Dynamic lookups

* CS

* CS
  • Loading branch information
sebastiandedeyne authored Jun 4, 2018
1 parent 632998d commit 71438a4
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 34 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

All notable changes to `laravel-view-components` will be documented in this file

## 1.1.0 - 2018-06-04
- Dynamically look up components to allow variables in paths

## 1.0.1 - 2018-06-02
- Fix config publishing

Expand Down
18 changes: 2 additions & 16 deletions src/CompileRenderDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

namespace Spatie\ViewComponents;

use Illuminate\Contracts\Support\Htmlable;
use InvalidArgumentException;

final class CompileRenderDirective
{
/** @var \Spatie\ViewComponents\ComponentFinder */
Expand All @@ -19,20 +16,9 @@ public function __invoke(string $expression): string
{
$expressionParts = explode(',', $expression, 2);

$componentClass = $this->componentFinder->find($expressionParts[0]);

if (!class_exists($componentClass)) {
throw new InvalidArgumentException("View component [{$componentClass}] not found.");
}

if (!array_key_exists(Htmlable::class, class_implements($componentClass))) {
throw new InvalidArgumentException(
"View component [{$componentClass}] must implement Illuminate\Support\Htmlable."
);
}

$componentPath = $expressionParts[0];
$props = trim($expressionParts[1] ?? '[]');

return "<?php echo app()->make({$componentClass}::class, {$props})->toHtml(); ?>";
return "<?php echo app(app(Spatie\ViewComponents\ComponentFinder::class)->find({$componentPath}), {$props})->toHtml(); ?>";
}
}
15 changes: 14 additions & 1 deletion src/ComponentFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Spatie\ViewComponents;

use InvalidArgumentException;
use Illuminate\Contracts\Support\Htmlable;

final class ComponentFinder
{
Expand All @@ -22,9 +23,21 @@ public function find(string $identifier): string
{
$identifier = $this->sanitizeIdentifier($identifier);

return class_exists($identifier)
$componentClass = class_exists($identifier)
? $identifier
: $this->expandComponentClassPath($identifier);

if (! class_exists($componentClass)) {
throw new InvalidArgumentException("View component [{$componentClass}] not found.");
}

if (! array_key_exists(Htmlable::class, class_implements($componentClass))) {
throw new InvalidArgumentException(
"View component [{$componentClass}] must implement Illuminate\Support\Htmlable."
);
}

return "{$componentClass}::class";
}

private function expandComponentClassPath(string $path): string
Expand Down
4 changes: 2 additions & 2 deletions tests/ClassNameTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class ClassNameTest extends TestCase
public function it_renders_a_component_from_a_classname()
{
$this->assertBladeCompilesTo(
'<?php echo app()->make(Spatie\ViewComponents\Tests\Stubs\MyComponent::class, [])->toHtml(); ?>',
'<?php echo app(app(Spatie\ViewComponents\ComponentFinder::class)->find(Spatie\ViewComponents\Tests\Stubs\MyComponent::class), [])->toHtml(); ?>',
'@render(Spatie\ViewComponents\Tests\Stubs\MyComponent::class)'
);
}
Expand All @@ -17,7 +17,7 @@ public function it_renders_a_component_from_a_classname()
public function it_renders_a_component_from_a_classname_with_props()
{
$this->assertBladeCompilesTo(
"<?php echo app()->make(Spatie\ViewComponents\Tests\Stubs\MyComponent::class, ['color' => 'red'])->toHtml(); ?>",
"<?php echo app(app(Spatie\ViewComponents\ComponentFinder::class)->find(Spatie\ViewComponents\Tests\Stubs\MyComponent::class), ['color' => 'red'])->toHtml(); ?>",
"@render(Spatie\ViewComponents\Tests\Stubs\MyComponent::class, ['color' => 'red'])"
);
}
Expand Down
7 changes: 4 additions & 3 deletions tests/ComponentValidationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
namespace Spatie\ViewComponents\Tests;

use InvalidArgumentException;
use Illuminate\Support\Facades\Blade;
use Spatie\ViewComponents\ComponentFinder;
use Spatie\ViewComponents\Tests\Stubs\NonHtmlable;

class ComponentValidationTest extends TestCase
{
Expand All @@ -13,7 +14,7 @@ public function it_fails_when_a_component_does_not_exist()
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("View component [App\Http\ViewComponents\DoesNotExist] not found.");

Blade::compileString("@render('doesNotExist')");
$this->app->make(ComponentFinder::class)->find('doesNotExist');
}

/** @test */
Expand All @@ -24,6 +25,6 @@ public function it_fails_when_a_component_does_not_implement_htmlable()
"View component [Spatie\ViewComponents\Tests\Stubs\NonHtmlable] must implement Illuminate\Support\Htmlable."
);

Blade::compileString("@render(Spatie\ViewComponents\Tests\Stubs\NonHtmlable::class)");
$this->app->make(ComponentFinder::class)->find(NonHtmlable::class);
}
}
11 changes: 6 additions & 5 deletions tests/NamespacesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
namespace Spatie\ViewComponents\Tests;

use InvalidArgumentException;
use Illuminate\Support\Facades\Blade;
use Spatie\ViewComponents\ComponentFinder;
use Spatie\ViewComponents\Tests\Stubs\MyComponent;

class NamespacesTest extends TestCase
{
Expand All @@ -18,9 +19,9 @@ protected function getEnvironmentSetUp($app)
/** @test */
public function it_renders_a_component_from_a_path_with_an_explicit_namespace()
{
$this->assertBladeCompilesTo(
'<?php echo app()->make(Spatie\ViewComponents\Tests\Stubs\MyComponent::class, [])->toHtml(); ?>',
"@render('stubs::myComponent')"
$this->assertEquals(
MyComponent::class.'::class',
$this->app->make(ComponentFinder::class)->find('stubs::myComponent')
);
}

Expand All @@ -32,6 +33,6 @@ public function it_throws_an_exception_when_a_namespace_doesnt_exist()
"View component namespace [nonExistingNamespace] doesn't exist."
);

Blade::compileString("@render('nonExistingNamespace::myComponent')");
$this->app->make(ComponentFinder::class)->find('nonExistingNamespace::myComponent');
}
}
18 changes: 11 additions & 7 deletions tests/RootNamespaceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

namespace Spatie\ViewComponents\Tests;

use Spatie\ViewComponents\ComponentFinder;
use Spatie\ViewComponents\Tests\Stubs\MyComponent;
use Spatie\ViewComponents\Tests\Stubs\Nested\NestedComponent;

class RootNamespaceTest extends TestCase
{
protected function getEnvironmentSetUp($app)
Expand All @@ -15,26 +19,26 @@ protected function getEnvironmentSetUp($app)
/** @test */
public function it_renders_a_component_from_a_path()
{
$this->assertBladeCompilesTo(
'<?php echo app()->make(Spatie\ViewComponents\Tests\Stubs\MyComponent::class, [])->toHtml(); ?>',
"@render('myComponent')"
$this->assertEquals(
MyComponent::class.'::class',
$this->app->make(ComponentFinder::class)->find('myComponent')
);
}

/** @test */
public function it_renders_a_component_from_a_nested_path()
{
$this->assertBladeCompilesTo(
'<?php echo app()->make(Spatie\ViewComponents\Tests\Stubs\Nested\NestedComponent::class, [])->toHtml(); ?>',
"@render('nested.nestedComponent')"
$this->assertEquals(
NestedComponent::class.'::class',
$this->app->make(ComponentFinder::class)->find('nested.nestedComponent')
);
}

/** @test */
public function it_renders_a_component_from_a_path_with_props()
{
$this->assertBladeCompilesTo(
"<?php echo app()->make(Spatie\ViewComponents\Tests\Stubs\MyComponent::class, ['color' => 'red'])->toHtml(); ?>",
"<?php echo app(app(Spatie\ViewComponents\ComponentFinder::class)->find('myComponent'), ['color' => 'red'])->toHtml(); ?>",
"@render('myComponent', ['color' => 'red'])"
);
}
Expand Down

0 comments on commit 71438a4

Please sign in to comment.