diff --git a/flight/template/View.php b/flight/template/View.php
index 1a3dc01..067d008 100644
--- a/flight/template/View.php
+++ b/flight/template/View.php
@@ -28,14 +28,24 @@ class View
protected array $vars = [];
private string $componentPrefix;
+ private string $componentsPath;
- /** @param string $path Path to templates directory */
+ /**
+ * @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 = ".",
- string $componentPrefix = 'f'
+ string $componentPrefix = 'f',
+ string $componentsPath = 'components'
) {
$this->path = $path;
$this->componentPrefix = $componentPrefix;
+ $this->componentsPath = $componentsPath;
}
/**
@@ -68,7 +78,7 @@ class View
/**
* Checks if a template variable is set
- * @return bool If key exists
+ * @return bool If key exists and is not `null`
*/
public function has(string $key): bool
{
@@ -193,7 +203,7 @@ class View
$props = [];
}
- $component = $this->fetch("components/$component", $props);
+ $component = $this->fetch("$this->componentsPath/$component", $props);
$view = str_replace($tag, $component, $view);
}
@@ -217,14 +227,17 @@ class View
*/
public function getTemplate(string $file): string
{
- if (!empty($this->extension) && (substr($file, -1 * strlen($this->extension)) !== $this->extension)) {
+ $fileDoesNotHaveExtension = substr($file, -strlen($this->extension)) !== $this->extension;
+
+ 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::normalizePath("$this->path/$file");
diff --git a/tests/ViewTest.php b/tests/ViewTest.php
index d85b5f6..69f1f61 100644
--- a/tests/ViewTest.php
+++ b/tests/ViewTest.php
@@ -250,6 +250,19 @@ class ViewTest extends TestCase
);
}
+ public function testItRendersComponentFromAnotherPath(): void
+ {
+ $view = new View(__DIR__ . '/views', 'f', __DIR__ . '/components');
+ $view->preserveVars = false;
+ $actual = $view->fetch('pages/page-with-component-from-another-path');
+ $expected = 'my-component-from-another-path';
+
+ self::assertSame(
+ self::removeIndentation(self::removeLineEndings($expected)),
+ self::removeIndentation(self::removeLineEndings($actual)),
+ );
+ }
+
public static function pagesDataProvider(): array
{
return [
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 0000000..b234a7d
--- /dev/null
+++ b/tests/components/my-component-from-another-path.php
@@ -0,0 +1 @@
+my-component-from-another-path
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 0000000..7ab559f
--- /dev/null
+++ b/tests/views/pages/page-with-component-from-another-path.php
@@ -0,0 +1 @@
+
\ No newline at end of file