diff --git a/.editorconfig b/.editorconfig index d3de6486..6110c5b3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,5 +11,5 @@ insert_final_newline = true [*.md] indent_size = 2 -[tests/views/*.php] +[tests/views/**/*] insert_final_newline = false diff --git a/composer.json b/composer.json index 70a09ca5..6a036543 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ { "name": "Mike Cao", "email": "mike@mikecao.com", - "homepage": "http://www.mikecao.com/", + "homepage": "https://mikecao.com", "role": "Original Developer" }, { diff --git a/flight/template/Component.php b/flight/template/Component.php new file mode 100644 index 00000000..83a465f1 --- /dev/null +++ b/flight/template/Component.php @@ -0,0 +1,20 @@ + + * @license [MIT](https://docs.flightphp.com/license) + * @copyright 2011 [Mike Cao](https://mikecao.com) */ class View { - /** Location of view templates. */ + /** Location of view templates */ public string $path; - /** File extension. */ + /** File extension */ public string $extension = '.php'; public bool $preserveVars = true; - /** - * View variables. - * - * @var array $vars - */ + /** @var array View variables */ protected array $vars = []; - /** Template file. */ - private string $template; + private string $componentPrefix; + private string $componentsPath; + private int $fetchDepth = 0; + /** @var array */ + private array $styles = []; + /** @var array */ + private array $scripts = []; /** - * Constructor. - * * @param string $path Path to templates directory + * @param string $componentPrefix Prefix for component tags. + * For example, if the prefix is `f`, then a component tag would look like `` + * @param string $componentsPath Path to components directory. + * If is a relative path, it will be relative to the `$path` property. + * **We recomment that you always use absolute paths for explicitness**. */ - public function __construct(string $path = '.') - { + public function __construct( + string $path = ".", + string $componentPrefix = 'f', + string $componentsPath = 'components' + ) { $this->path = $path; + $this->componentPrefix = $componentPrefix; + $this->componentsPath = $componentsPath; } /** - * Gets a template variable. - * + * Gets a template variable * @return mixed Variable value or `null` if doesn't exists */ public function get(string $key) @@ -53,16 +65,14 @@ public function get(string $key) } /** - * Sets a template variable. - * - * @param string|iterable $key + * Sets a template variable + * @param string|array $key * @param mixed $value Value - * - * @return self + * @return $this */ - public function set($key, $value = null): self + public function set($key, $value = null) { - if (\is_iterable($key)) { + if (is_array($key)) { foreach ($key as $k => $v) { $this->vars[$k] = $v; } @@ -74,9 +84,8 @@ public function set($key, $value = null): self } /** - * Checks if a template variable is set. - * - * @return bool If key exists + * Checks if a template variable is set + * @return bool If key exists and is not `null` */ public function has(string $key): bool { @@ -84,11 +93,10 @@ public function has(string $key): bool } /** - * Unsets a template variable. If no key is passed in, clear all variables. - * + * Unsets a template variable. If no key is passed in, clear all variables * @return $this */ - public function clear(?string $key = null): self + public function clear(?string $key = null) { if ($key === null) { $this->vars = []; @@ -100,104 +108,242 @@ public function clear(?string $key = null): self } /** - * Renders a template. - * + * Renders a template * @param string $file Template file * @param ?array $templateData Template data - * - * @throws \Exception If template not found + * @throws Exception If template not found */ public function render(string $file, ?array $templateData = null): void { - $this->template = $this->getTemplate($file); - - if (!\file_exists($this->template)) { - $normalized_path = self::normalizePath($this->template); - throw new \Exception("Template file not found: {$normalized_path}."); - } - - \extract($this->vars); - - if (\is_array($templateData) === true) { - \extract($templateData); - - if ($this->preserveVars === true) { - $this->vars = \array_merge($this->vars, $templateData); - } - } - - include $this->template; + echo $this->fetch($file, $templateData); } /** - * Gets the output of a template. - * + * Gets the output of a template * @param string $file Template file * @param ?array $data Template data - * * @return string Output of template */ public function fetch(string $file, ?array $data = null): string { - \ob_start(); + if ($this->fetchDepth === 0) { + $this->styles = []; + $this->scripts = []; + } + + $this->fetchDepth++; + + try { + $template = $this->getTemplate($file); + + if (!$this->exists($file)) { + throw new Exception("Template file not found: $template."); + } + + extract($this->vars); + + if (is_array($data)) { + extract($data); + + if ($this->preserveVars) { + $this->vars += $data; + } + } + + ob_start(); + $component = include $template; + + switch (true) { + case is_callable($component): + $arguments = $this->getCallableArguments($component, $data); + $view = $component(...$arguments); + ob_end_clean(); + + break; + case $component instanceof Component: + $view = $component->html(); + $css = $component->css(); + $js = $component->js(); + + if ($css && !array_key_exists($template, $this->styles)) { + $view .= $this->renderComponentStyle($css); + + $this->styles[$template] = true; + } + + if ($js && !array_key_exists($template, $this->scripts)) { + $view .= $this->renderComponentScript($js); + + $this->scripts[$template] = true; + } + + ob_end_clean(); + + break; + default: + $view = ob_get_clean(); + } + + preg_match_all( + "/<$this->componentPrefix-(?[a-z-]+)\s*(?([a-z]+=\"[^\"]+\"\s*)*)?\s*\/>/", + $view, + $tagsMatches, + ); + + $tagsMatches = array_filter($tagsMatches); - $this->render($file, $data); + foreach ($tagsMatches[0] ?? [] as $tagIndex => $match) { + $tag = $match; + $component = $tagsMatches['component'][$tagIndex]; + $props = $tagsMatches['props'][$tagIndex] ?? ''; - return \ob_get_clean(); + preg_match_all( + '/(?[a-z]+)="(?[^"]+)"/', + $props, + $propsMatches, + ); + + $propsMatches = array_filter($propsMatches); + + if ($propsMatches) { + $props = []; + + foreach (array_keys($propsMatches[0]) as $propIndex) { + $name = $propsMatches['name'][$propIndex]; + $value = $propsMatches['value'][$propIndex]; + $props[$name] = $value; + } + } else { + $props = []; + } + + $component = $this->fetch("$this->componentsPath/$component", $props); + $tagPosition = strpos($view, $tag); + + if ($tagPosition === false) { + continue; + } + + $view = substr_replace($view, $component, $tagPosition, strlen($tag)); + } + + return $view; + } finally { + $this->fetchDepth--; + } } /** - * Checks if a template file exists. - * + * Checks if a template file exists * @param string $file Template file - * * @return bool Template file exists */ public function exists(string $file): bool { - return \file_exists($this->getTemplate($file)); + return file_exists($this->getTemplate($file)); } /** - * Gets the full path to a template file. - * + * Gets the full path to a template file * @param string $file Template file - * * @return string Template file location */ public function getTemplate(string $file): string { - $ext = $this->extension; + $fileDoesNotHaveExtension = substr($file, -strlen($this->extension)) !== $this->extension; - if (!empty($ext) && (\substr($file, -1 * \strlen($ext)) != $ext)) { - $file .= $ext; + if ($fileDoesNotHaveExtension) { + $file .= $this->extension; } - $is_windows = \strtoupper(\substr(PHP_OS, 0, 3)) === 'WIN'; + $isLinuxAbsolutePath = $file[0] === '/'; + $isWindowsAbsolutePath = PHP_OS === 'WINNT' && $file[1] === ':'; - if ((\substr($file, 0, 1) === '/') || ($is_windows && \substr($file, 1, 1) === ':')) { - return $file; + if ($isLinuxAbsolutePath || $isWindowsAbsolutePath) { + return $this::normalizePath($file); } - return $this->path . DIRECTORY_SEPARATOR . $file; + return $this::normalizePath("$this->path/$file"); } /** - * Displays escaped output. - * + * Displays escaped output * @param string $str String to escape - * * @return string Escaped string */ public function e(string $str): string { - $value = \htmlentities($str); + $value = htmlentities($str); echo $value; + return $value; } - protected static function normalizePath(string $path, string $separator = DIRECTORY_SEPARATOR): string + protected static function normalizePath( + string $path, + string $separator = DIRECTORY_SEPARATOR + ): string { + return str_replace(['\\', '/'], $separator, $path); + } + + /** + * @param callable $component + * @param ?array $data + * @return array + */ + private function getCallableArguments(callable $component, ?array $data): array + { + if (!is_array($data) || !$data) { + return []; + } + + $arguments = []; + $remainingData = $data; + $reflection = new ReflectionFunction(Closure::fromCallable($component)); + + foreach ($reflection->getParameters() as $parameter) { + if ($parameter->isVariadic()) { + foreach ($remainingData as $value) { + $arguments[] = $value; + } + + break; + } + + $name = $parameter->getName(); + + if (array_key_exists($name, $remainingData)) { + $arguments[] = $remainingData[$name]; + unset($remainingData[$name]); + } + } + + return $arguments; + } + + private function renderComponentStyle(string $css): string + { + if (preg_match('/^\s*]*>.*<\/style>\s*$/is', $css) === 1) { + return $css; + } + + return << + $css + + html; + } + + private function renderComponentScript(string $js): string { - return \str_replace(['\\', '/'], $separator, $path); + if (preg_match('/^\s*]*>.*<\/script>\s*$/is', $js) === 1) { + return $js; + } + + return << + $js + + html; } } diff --git a/tests/ViewTest.php b/tests/ViewTest.php index e57afd09..1357fb70 100644 --- a/tests/ViewTest.php +++ b/tests/ViewTest.php @@ -14,101 +14,83 @@ class ViewTest extends TestCase protected function setUp(): void { - $this->view = new View(); - $this->view->path = __DIR__ . '/views'; + $this->view = new View(__DIR__ . '/views'); } - // Set template variables public function testVariables(): void { $this->view->set('test', 123); - $this->assertEquals(123, $this->view->get('test')); - - $this->assertTrue($this->view->has('test')); - $this->assertTrue(!$this->view->has('unknown')); + self::assertSame(123, $this->view->get('test')); + self::assertTrue($this->view->has('test')); + self::assertFalse($this->view->has('unknown')); $this->view->clear('test'); - $this->assertNull($this->view->get('test')); + self::assertNull($this->view->get('test')); } public function testMultipleVariables(): void { - $this->view->set([ - 'test' => 123, - 'foo' => 'bar' - ]); + $this->view->set(['test' => 123, 'foo' => 'bar']); - $this->assertEquals(123, $this->view->get('test')); - $this->assertEquals('bar', $this->view->get('foo')); + self::assertSame(123, $this->view->get('test')); + self::assertSame('bar', $this->view->get('foo')); $this->view->clear(); - $this->assertNull($this->view->get('test')); - $this->assertNull($this->view->get('foo')); + self::assertNull($this->view->get('test')); + self::assertNull($this->view->get('foo')); } - // Check if template files exist public function testTemplateExists(): void { - $this->assertTrue($this->view->exists('hello.php')); - $this->assertTrue(!$this->view->exists('unknown.php')); + self::assertTrue($this->view->exists('hello.php')); + self::assertFalse($this->view->exists('unknown.php')); } - // Render a template public function testRender(): void { $this->view->render('hello', ['name' => 'Bob']); - $this->expectOutputString('Hello, Bob!'); + self::expectOutputString('Hello, Bob!'); } public function testRenderBadFilePath(): void { - $this->expectException(Exception::class); $exception_message = sprintf( 'Template file not found: %s%sviews%sbadfile.php', __DIR__, DIRECTORY_SEPARATOR, - DIRECTORY_SEPARATOR + DIRECTORY_SEPARATOR, ); - $this->expectExceptionMessage($exception_message); + + self::expectException(Exception::class); + self::expectExceptionMessage($exception_message); $this->view->render('badfile'); } - // Fetch template output public function testFetch(): void { $output = $this->view->fetch('hello', ['name' => 'Bob']); - $this->assertEquals('Hello, Bob!', $output); + self::assertSame('Hello, Bob!', $output); } - // Default extension public function testTemplateWithExtension(): void { - $this->view->set('name', 'Bob'); + $this->view->render('hello.php', ['name' => 'Bob']); - $this->view->render('hello.php'); - - $this->expectOutputString('Hello, Bob!'); + self::expectOutputString('Hello, Bob!'); } - // Custom extension public function testTemplateWithCustomExtension(): void { - $this->view->set('name', 'Bob'); - $this->view->extension = '.html'; - - ob_start(); - $this->view->render('world'); - $html = ob_get_clean(); - $html = str_replace(["\r\n", "\n"], '', $html); - echo $html; + self::expectOutputString('Hello world, Bob!'); - $this->expectOutputString("Hello world, Bob!"); + $this->view->extension = '.html'; + $this->view->render('world', ['name' => 'Bob']); } public function testGetTemplateAbsolutePath(): void @@ -116,48 +98,64 @@ public function testGetTemplateAbsolutePath(): void $tmpfile = tmpfile(); $this->view->extension = ''; $file_path = stream_get_meta_data($tmpfile)['uri']; - $this->assertEquals($file_path, $this->view->getTemplate($file_path)); + + self::assertSame($file_path, $this->view->getTemplate($file_path)); } public function testE(): void { - $this->expectOutputString('<script>'); + $expectedString = '<script>'; + + self::expectOutputString($expectedString); + $result = $this->view->e(' + html, + ], + [ + 'page-with-class-component-with-custom-script-tag', + <<<'html' + my-class-component-with-custom-script-tag + + html, + ], + [ + 'page-with-class-component-that-extends-another-class-component', + <<<'html' + another-class-component extended by my-class-component-that-extends-another-class-component + html, + ], + [ + 'page-with-component-with-one-prop', + <<<'html' + + +

Hello, James

+ + + html, + ['name' => 'James'], + ], + [ + 'page-with-component-with-one-prop', + <<<'html' + + +

Hello, Victoria

+ + + html, + ['name' => 'Victoria'], + ], + [ + 'page-with-component-with-two-props', + <<<'html' + + +

Hello, Astronaut Victoria

+ + + html, + ['name' => 'Victoria', 'occupation' => 'Astronaut'], + ], + [ + 'page-with-three-different-components', + <<<'html' + my-component + my-functional-component + my-class-component + html, + ], + [ + 'page-with-component-with-prop-which-value-contains-spaces-and-numbers', + <<<'html' +

Hello, Constantine 1st the Great

+ html, + ['name' => 'Constantine 1st the Great'], + ], + [ + 'page-two-same-components-with-one-style-and-script-tag', + <<<'html' + + my-class-component-with-styles + + + + my-class-component-with-styles + + my-class-component-with-scripts + + my-class-component-with-scripts + html, + ], + ]; + } + + /** @dataProvider prefixesDataProvider */ + public function testRenderComponentsWithDifferentPrefixes(string $prefix): void + { + $view = new View(__DIR__ . '/views', $prefix); + $view->preserveVars = false; + $actual = $view->fetch('pages/page-with-component-with-custom-prefix', compact('prefix')); + $expected = 'my-component'; + + self::assertSame( + self::removeIndentation(self::removeLineEndings($expected)), + self::removeIndentation(self::removeLineEndings($actual)), + ); + } + + public static function prefixesDataProvider(): array + { + return [ + ['x'], + ]; + } + + private static function removeLineEndings(string $subject): string + { + return str_replace(["\r", "\n"], '', $subject); + } + + private static function removeIndentation(string $subject): string + { + return preg_replace('/\s{2,}/', '', $subject); + } } diff --git a/tests/components/my-component-from-another-path.php b/tests/components/my-component-from-another-path.php new file mode 100644 index 00000000..b234a7d2 --- /dev/null +++ b/tests/components/my-component-from-another-path.php @@ -0,0 +1 @@ +my-component-from-another-path diff --git a/tests/views/components/another-class-component.php b/tests/views/components/another-class-component.php new file mode 100644 index 00000000..27313737 --- /dev/null +++ b/tests/views/components/another-class-component.php @@ -0,0 +1,19 @@ +Hello, \ No newline at end of file diff --git a/tests/views/components/greeting.php b/tests/views/components/greeting.php new file mode 100644 index 00000000..3a8fd49d --- /dev/null +++ b/tests/views/components/greeting.php @@ -0,0 +1 @@ +

Hello,

\ No newline at end of file diff --git a/tests/views/components/my-class-component-that-extends-another-class-component.php b/tests/views/components/my-class-component-that-extends-another-class-component.php new file mode 100644 index 00000000..c071b1ef --- /dev/null +++ b/tests/views/components/my-class-component-that-extends-another-class-component.php @@ -0,0 +1,16 @@ + + console.log('my-class-component-with-custom-script-tag') + + js; + } +}; diff --git a/tests/views/components/my-class-component-with-custom-style-tag.php b/tests/views/components/my-class-component-with-custom-style-tag.php new file mode 100644 index 00000000..f6c65b88 --- /dev/null +++ b/tests/views/components/my-class-component-with-custom-style-tag.php @@ -0,0 +1,28 @@ + + my-class-component-with-custom-style-tag + + html; + } + + public function css(): string + { + return <<<'css' + + css; + } +}; diff --git a/tests/views/components/my-class-component-with-props.php b/tests/views/components/my-class-component-with-props.php new file mode 100644 index 00000000..66abcad6 --- /dev/null +++ b/tests/views/components/my-class-component-with-props.php @@ -0,0 +1,22 @@ +name = $name; + $this->occupation = $occupation; + } + + public function html(): string + { + return "class-component-with-props: $this->occupation $this->name"; + } +}; diff --git a/tests/views/components/my-class-component-with-scripts.php b/tests/views/components/my-class-component-with-scripts.php new file mode 100644 index 00000000..3e3976c9 --- /dev/null +++ b/tests/views/components/my-class-component-with-scripts.php @@ -0,0 +1,22 @@ + + my-class-component-with-styles + + html; + } + + #[Override] + public function css(): string + { + return <<<'css' + .my-class-component-with-styles { + color: red; + } + css; + } +}; \ No newline at end of file diff --git a/tests/views/components/my-class-component.php b/tests/views/components/my-class-component.php new file mode 100644 index 00000000..e44e7d03 --- /dev/null +++ b/tests/views/components/my-class-component.php @@ -0,0 +1,14 @@ + + my-component-with-subcomponent + + \ No newline at end of file diff --git a/tests/views/components/my-component.php b/tests/views/components/my-component.php new file mode 100644 index 00000000..e3ecf456 --- /dev/null +++ b/tests/views/components/my-component.php @@ -0,0 +1 @@ +my-component \ No newline at end of file diff --git a/tests/views/components/my-functional-component-with-individual-props.php b/tests/views/components/my-functional-component-with-individual-props.php new file mode 100644 index 00000000..9f3bdb92 --- /dev/null +++ b/tests/views/components/my-functional-component-with-individual-props.php @@ -0,0 +1,6 @@ + + "functional-component-with-individual-props: $occupation $name"; diff --git a/tests/views/components/my-functional-component-with-props.php b/tests/views/components/my-functional-component-with-props.php new file mode 100644 index 00000000..ef8856e7 --- /dev/null +++ b/tests/views/components/my-functional-component-with-props.php @@ -0,0 +1,9 @@ + sprintf( + 'functional-component-with-props: %s %s', + $props[1] ?? '', + $props[0] ?? '' +); diff --git a/tests/views/components/my-functional-component.php b/tests/views/components/my-functional-component.php new file mode 100644 index 00000000..73f98da7 --- /dev/null +++ b/tests/views/components/my-functional-component.php @@ -0,0 +1,5 @@ + 'my-functional-component'; \ No newline at end of file diff --git a/tests/views/components/subcomponent.php b/tests/views/components/subcomponent.php new file mode 100644 index 00000000..8aca66b3 --- /dev/null +++ b/tests/views/components/subcomponent.php @@ -0,0 +1 @@ +subcomponent \ No newline at end of file diff --git a/tests/views/hello.php b/tests/views/hello.php index 86a9b806..8551a874 100644 --- a/tests/views/hello.php +++ b/tests/views/hello.php @@ -1 +1 @@ -Hello, ! \ No newline at end of file +Hello, ! \ No newline at end of file diff --git a/tests/views/pages/page-two-same-components-with-one-style-and-script-tag.php b/tests/views/pages/page-two-same-components-with-one-style-and-script-tag.php new file mode 100644 index 00000000..8dfdf979 --- /dev/null +++ b/tests/views/pages/page-two-same-components-with-one-style-and-script-tag.php @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/views/pages/page-with-class-component-that-extends-another-class-component.php b/tests/views/pages/page-with-class-component-that-extends-another-class-component.php new file mode 100644 index 00000000..2fef30ab --- /dev/null +++ b/tests/views/pages/page-with-class-component-that-extends-another-class-component.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/views/pages/page-with-class-component-with-custom-script-tag.php b/tests/views/pages/page-with-class-component-with-custom-script-tag.php new file mode 100644 index 00000000..bec475ec --- /dev/null +++ b/tests/views/pages/page-with-class-component-with-custom-script-tag.php @@ -0,0 +1 @@ + diff --git a/tests/views/pages/page-with-class-component-with-custom-style-tag.php b/tests/views/pages/page-with-class-component-with-custom-style-tag.php new file mode 100644 index 00000000..5f210436 --- /dev/null +++ b/tests/views/pages/page-with-class-component-with-custom-style-tag.php @@ -0,0 +1 @@ + diff --git a/tests/views/pages/page-with-class-component-with-props.php b/tests/views/pages/page-with-class-component-with-props.php new file mode 100644 index 00000000..a2bd6d90 --- /dev/null +++ b/tests/views/pages/page-with-class-component-with-props.php @@ -0,0 +1 @@ + diff --git a/tests/views/pages/page-with-class-component-with-scripts.php b/tests/views/pages/page-with-class-component-with-scripts.php new file mode 100644 index 00000000..0fcd56fc --- /dev/null +++ b/tests/views/pages/page-with-class-component-with-scripts.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/views/pages/page-with-class-component-with-styles.php b/tests/views/pages/page-with-class-component-with-styles.php new file mode 100644 index 00000000..3ca6a359 --- /dev/null +++ b/tests/views/pages/page-with-class-component-with-styles.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/views/pages/page-with-class-component.php b/tests/views/pages/page-with-class-component.php new file mode 100644 index 00000000..76a7423d --- /dev/null +++ b/tests/views/pages/page-with-class-component.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/views/pages/page-with-component-from-another-path.php b/tests/views/pages/page-with-component-from-another-path.php new file mode 100644 index 00000000..7ab559fa --- /dev/null +++ b/tests/views/pages/page-with-component-from-another-path.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/views/pages/page-with-component-with-custom-prefix.php b/tests/views/pages/page-with-component-with-custom-prefix.php new file mode 100644 index 00000000..46b3dcee --- /dev/null +++ b/tests/views/pages/page-with-component-with-custom-prefix.php @@ -0,0 +1 @@ +<-my-component /> \ No newline at end of file diff --git a/tests/views/pages/page-with-component-with-new-syntax.php b/tests/views/pages/page-with-component-with-new-syntax.php new file mode 100644 index 00000000..31ebaab3 --- /dev/null +++ b/tests/views/pages/page-with-component-with-new-syntax.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/views/pages/page-with-component-with-old-syntax.php b/tests/views/pages/page-with-component-with-old-syntax.php new file mode 100644 index 00000000..1aa97028 --- /dev/null +++ b/tests/views/pages/page-with-component-with-old-syntax.php @@ -0,0 +1 @@ +render('components/my-component') ?> \ No newline at end of file diff --git a/tests/views/pages/page-with-component-with-one-prop.php b/tests/views/pages/page-with-component-with-one-prop.php new file mode 100644 index 00000000..9839e1a4 --- /dev/null +++ b/tests/views/pages/page-with-component-with-one-prop.php @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/views/pages/page-with-component-with-prop-which-value-contains-spaces-and-numbers.php b/tests/views/pages/page-with-component-with-prop-which-value-contains-spaces-and-numbers.php new file mode 100644 index 00000000..622b8339 --- /dev/null +++ b/tests/views/pages/page-with-component-with-prop-which-value-contains-spaces-and-numbers.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/views/pages/page-with-component-with-subcomponent.php b/tests/views/pages/page-with-component-with-subcomponent.php new file mode 100644 index 00000000..d0328095 --- /dev/null +++ b/tests/views/pages/page-with-component-with-subcomponent.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/views/pages/page-with-component-with-two-props.php b/tests/views/pages/page-with-component-with-two-props.php new file mode 100644 index 00000000..6cb90459 --- /dev/null +++ b/tests/views/pages/page-with-component-with-two-props.php @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/views/pages/page-with-functional-component-with-individual-props.php b/tests/views/pages/page-with-functional-component-with-individual-props.php new file mode 100644 index 00000000..f77480af --- /dev/null +++ b/tests/views/pages/page-with-functional-component-with-individual-props.php @@ -0,0 +1 @@ + diff --git a/tests/views/pages/page-with-functional-component-with-props.php b/tests/views/pages/page-with-functional-component-with-props.php new file mode 100644 index 00000000..dddef9f5 --- /dev/null +++ b/tests/views/pages/page-with-functional-component-with-props.php @@ -0,0 +1 @@ + diff --git a/tests/views/pages/page-with-functional-component.php b/tests/views/pages/page-with-functional-component.php new file mode 100644 index 00000000..07fcec24 --- /dev/null +++ b/tests/views/pages/page-with-functional-component.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/views/pages/page-with-multiple-components.php b/tests/views/pages/page-with-multiple-components.php new file mode 100644 index 00000000..f7836b44 --- /dev/null +++ b/tests/views/pages/page-with-multiple-components.php @@ -0,0 +1,7 @@ +
    + +
  • + +
  • + +
\ No newline at end of file diff --git a/tests/views/pages/page-with-three-different-components.php b/tests/views/pages/page-with-three-different-components.php new file mode 100644 index 00000000..a17fe68f --- /dev/null +++ b/tests/views/pages/page-with-three-different-components.php @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/views/world.html b/tests/views/world.html index f4c856e9..d274ca39 100644 --- a/tests/views/world.html +++ b/tests/views/world.html @@ -1 +1 @@ -Hello world, ! +Hello world, ! \ No newline at end of file