diff --git a/app/controllers/DirectoryController.php b/app/controllers/DirectoryController.php
index 3b89675..5b4c598 100644
--- a/app/controllers/DirectoryController.php
+++ b/app/controllers/DirectoryController.php
@@ -2,6 +2,7 @@
namespace App\Controllers;
+use PHLAK\Config\Config;
use Slim\Psr7\Request;
use Slim\Psr7\Response;
use Slim\Views\Twig;
@@ -9,16 +10,21 @@ use Symfony\Component\Finder\Finder;
class DirectoryController
{
+ /** @var Config App configuration component */
+ protected $config;
+
/** @var Twig Twig templating component */
protected $view;
/**
* Create a new DirectoryController object.
*
- * @param \Slim\Views\Twig $view
+ * @param \PHLAK\Config\Config $config
+ * @param \Slim\Views\Twig $view
*/
- public function __construct(Twig $view)
+ public function __construct(Config $config, Twig $view)
{
+ $this->config = $config;
$this->view = $view;
}
@@ -35,10 +41,40 @@ class DirectoryController
{
$files = new Finder();
$files->in($path)->depth(0)->followLinks();
- $files->sortByName($useNatrualSort = true)->sortByType();
+ $files->exclude($this->config->get('hidden_files', []));
+ $files->ignoreVCS($this->config->get('ignore_vcs_files', false));
+ $files->sortByName(true)->sortByType();
+ // TODO: Filter out hidden files
return $this->view->render($response, 'index.twig', [
- 'files' => $files
+ 'breadcrumbs' => $this->breadcrumbs($path),
+ 'files' => $files,
]);
}
+
+ /**
+ * Build an array of breadcrumbs for a given path.
+ *
+ * @param string $path
+ *
+ * @return array
+ */
+ protected function breadcrumbs(string $path): array
+ {
+ $breadcrumbs = [];
+ $crumbsPath = '';
+
+ foreach (array_filter(explode('/', $path)) as $crumb) {
+ $crumbsPath .= "/{$crumb}";
+
+ $breadcrumbs[] = [
+ 'name' => $crumb,
+ 'path' => $crumbsPath
+ ];
+ }
+
+ return array_filter($breadcrumbs, function ($crumb) {
+ return $crumb['name'] !== '.';
+ });
+ }
}
diff --git a/app/support/helpers.php b/app/support/helpers.php
new file mode 100644
index 0000000..4aedda7
--- /dev/null
+++ b/app/support/helpers.php
@@ -0,0 +1,31 @@
+
+
Directory Lister
-
- {% for file in files %}
- -
- {{ file.getBasename }}
-
- {% endfor %}
-
+
diff --git a/app/themes/default/package-lock.json b/app/themes/default/package-lock.json
index b0badf4..8159578 100644
--- a/app/themes/default/package-lock.json
+++ b/app/themes/default/package-lock.json
@@ -836,6 +836,12 @@
"to-fast-properties": "2.0.0"
}
},
+ "@fortawesome/fontawesome-free": {
+ "version": "5.11.2",
+ "resolved": "https://npm.fontawesome.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.11.2.tgz",
+ "integrity": "sha512-XiUPoS79r1G7PcpnNtq85TJ7inJWe0v+b5oZJZKb0pGHNIV6+UiNeQWiFGmuQ0aj7GEhnD/v9iqxIsjuRKtEnQ==",
+ "dev": true
+ },
"@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@@ -1137,6 +1143,51 @@
"integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==",
"dev": true
},
+ "adjust-sourcemap-loader": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz",
+ "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==",
+ "dev": true,
+ "requires": {
+ "assert": "1.4.1",
+ "camelcase": "5.0.0",
+ "loader-utils": "1.2.3",
+ "object-path": "0.11.4",
+ "regex-parser": "2.2.10"
+ },
+ "dependencies": {
+ "assert": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+ "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+ "dev": true,
+ "requires": {
+ "util": "0.10.3"
+ }
+ },
+ "camelcase": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
+ "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==",
+ "dev": true
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+ "dev": true
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.1"
+ }
+ }
+ }
+ },
"ajv": {
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
@@ -1230,6 +1281,12 @@
"sprintf-js": "1.0.3"
}
},
+ "arity-n": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz",
+ "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=",
+ "dev": true
+ },
"arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -2018,6 +2075,17 @@
}
}
},
+ "clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4",
+ "kind-of": "6.0.2",
+ "shallow-clone": "3.0.1"
+ }
+ },
"coa": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
@@ -2104,6 +2172,15 @@
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
"dev": true
},
+ "compose-function": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz",
+ "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=",
+ "dev": true,
+ "requires": {
+ "arity-n": "1.0.4"
+ }
+ },
"compressible": {
"version": "2.0.17",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz",
@@ -2326,6 +2403,58 @@
"sha.js": "2.4.11"
}
},
+ "cross-env": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz",
+ "integrity": "sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "7.0.1"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
+ "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==",
+ "dev": true,
+ "requires": {
+ "path-key": "3.1.0",
+ "shebang-command": "2.0.0",
+ "which": "2.0.1"
+ }
+ },
+ "path-key": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.0.tgz",
+ "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.1.tgz",
+ "integrity": "sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==",
+ "dev": true,
+ "requires": {
+ "isexe": "2.0.0"
+ }
+ }
+ }
+ },
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -2372,6 +2501,18 @@
"randomfill": "1.0.4"
}
},
+ "css": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+ "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.4",
+ "source-map": "0.6.1",
+ "source-map-resolve": "0.5.2",
+ "urix": "0.1.0"
+ }
+ },
"css-color-names": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
@@ -2616,6 +2757,22 @@
"integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
"dev": true
},
+ "d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "dev": true,
+ "requires": {
+ "es5-ext": "0.10.52",
+ "type": "1.2.0"
+ }
+ },
+ "de-indent": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+ "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=",
+ "dev": true
+ },
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@@ -3047,6 +3204,38 @@
"is-symbol": "1.0.2"
}
},
+ "es5-ext": {
+ "version": "0.10.52",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.52.tgz",
+ "integrity": "sha512-bWCbE9fbpYQY4CU6hJbJ1vSz70EClMlDgJ7BmwI+zEJhxrwjesZRPglGJlsZhu0334U3hI+gaspwksH9IGD6ag==",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "2.0.3",
+ "es6-symbol": "3.1.3",
+ "next-tick": "1.0.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+ "dev": true,
+ "requires": {
+ "d": "1.0.1",
+ "es5-ext": "0.10.52",
+ "es6-symbol": "3.1.3"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "dev": true,
+ "requires": {
+ "d": "1.0.1",
+ "ext": "1.1.2"
+ }
+ },
"es6-templates": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz",
@@ -3284,6 +3473,23 @@
}
}
},
+ "ext": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.1.2.tgz",
+ "integrity": "sha512-/KLjJdTNyDepCihrk4HQt57nAE1IRCEo5jUt+WgWGCr1oARhibDvmI2DMcSNWood1T9AUWwq+jaV1wvRqaXfnA==",
+ "dev": true,
+ "requires": {
+ "type": "2.0.0"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz",
+ "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==",
+ "dev": true
+ }
+ }
+ },
"extend-shallow": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
@@ -4250,6 +4456,33 @@
"path-is-absolute": "1.0.1"
}
},
+ "glob-all": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-all/-/glob-all-3.1.0.tgz",
+ "integrity": "sha1-iRPd+17hrHgSZWJBsD1SF8ZLAqs=",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.5",
+ "yargs": "1.2.6"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz",
+ "integrity": "sha1-md9lelJXTCHJBXSX33QnkLK0wN4=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.2.6.tgz",
+ "integrity": "sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.1.0"
+ }
+ }
+ }
+ },
"glob-parent": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
@@ -5263,6 +5496,16 @@
}
}
},
+ "laravel-mix-purgecss": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/laravel-mix-purgecss/-/laravel-mix-purgecss-4.2.0.tgz",
+ "integrity": "sha512-hzphHnhK3xPiv19QhCnhuvSUK4vmPB/76S6EHDb3WPa6Oz7aOlBREXLhg57ejiisy9GdVKw5DZjYwk3JLjAkYA==",
+ "dev": true,
+ "requires": {
+ "glob-all": "3.1.0",
+ "purgecss-webpack-plugin": "1.6.0"
+ }
+ },
"last-call-webpack-plugin": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz",
@@ -5708,6 +5951,12 @@
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"dev": true
},
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+ "dev": true
+ },
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -5916,6 +6165,12 @@
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
},
+ "object-path": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz",
+ "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=",
+ "dev": true
+ },
"object-visit": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
@@ -7150,6 +7405,85 @@
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
+ "purgecss": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-1.4.1.tgz",
+ "integrity": "sha512-5jONV/D/3nfa+lC425+LA+OWe5/LDn4a79cac+TnzJq3VczwnWlpIDdW275hHsGhkzIlqATQsYFLW7or0cSwNQ==",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.5",
+ "postcss": "7.0.21",
+ "postcss-selector-parser": "6.0.2",
+ "yargs": "14.2.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "7.0.3",
+ "is-fullwidth-code-point": "2.0.0",
+ "strip-ansi": "5.2.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "4.1.0"
+ }
+ },
+ "yargs": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.0.tgz",
+ "integrity": "sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg==",
+ "dev": true,
+ "requires": {
+ "cliui": "5.0.0",
+ "decamelize": "1.2.0",
+ "find-up": "3.0.0",
+ "get-caller-file": "2.0.5",
+ "require-directory": "2.1.1",
+ "require-main-filename": "2.0.0",
+ "set-blocking": "2.0.0",
+ "string-width": "3.1.0",
+ "which-module": "2.0.0",
+ "y18n": "4.0.0",
+ "yargs-parser": "15.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz",
+ "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "5.3.1",
+ "decamelize": "1.2.0"
+ }
+ }
+ }
+ },
+ "purgecss-webpack-plugin": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/purgecss-webpack-plugin/-/purgecss-webpack-plugin-1.6.0.tgz",
+ "integrity": "sha512-rVrTWYsOTShUvD5gl0q/krkwTlBUILlyoqRk2XoujNm2dETt276yvK4vP9oyXVPSQyaMCjjP5YPMCq9PNgIlJQ==",
+ "dev": true,
+ "requires": {
+ "purgecss": "1.4.1",
+ "webpack-sources": "1.4.3"
+ }
+ },
"q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
@@ -7321,6 +7655,12 @@
"safe-regex": "1.1.0"
}
},
+ "regex-parser": {
+ "version": "2.2.10",
+ "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz",
+ "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==",
+ "dev": true
+ },
"regexp.prototype.flags": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz",
@@ -7468,6 +7808,52 @@
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
"dev": true
},
+ "resolve-url-loader": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.0.tgz",
+ "integrity": "sha512-2QcrA+2QgVqsMJ1Hn5NnJXIGCX1clQ1F6QJTqOeiaDw9ACo1G2k+8/shq3mtqne03HOFyskAClqfxKyFBriXZg==",
+ "dev": true,
+ "requires": {
+ "adjust-sourcemap-loader": "2.0.0",
+ "camelcase": "5.0.0",
+ "compose-function": "3.0.3",
+ "convert-source-map": "1.6.0",
+ "es6-iterator": "2.0.3",
+ "loader-utils": "1.2.3",
+ "postcss": "7.0.14",
+ "rework": "1.0.1",
+ "rework-visit": "1.0.0",
+ "source-map": "0.6.1"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
+ "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.14",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz",
+ "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.4.2",
+ "source-map": "0.6.1",
+ "supports-color": "6.1.0"
+ }
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "3.0.0"
+ }
+ }
+ }
+ },
"ret": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
@@ -7480,6 +7866,30 @@
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
"dev": true
},
+ "rework": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz",
+ "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "0.3.5",
+ "css": "2.2.4"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz",
+ "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=",
+ "dev": true
+ }
+ }
+ },
+ "rework-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz",
+ "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=",
+ "dev": true
+ },
"rgb-regex": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
@@ -7541,6 +7951,40 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true
},
+ "sass": {
+ "version": "1.23.2",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.23.2.tgz",
+ "integrity": "sha512-ZfOl81QxcWmjxOgjPbyog3uELzOxd4X9OaqEIAi9r/d2kEjtEYaMAD9a3E+xgjcKeP3NDLMhU9GB/WMv+rAeSw==",
+ "dev": true,
+ "requires": {
+ "chokidar": "2.1.8"
+ }
+ },
+ "sass-loader": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.0.tgz",
+ "integrity": "sha512-+qeMu563PN7rPdit2+n5uuYVR0SSVwm0JsOUsaJXzgYcClWSlmX0iHDnmeOobPkf5kUglVot3QS6SyLyaQoJ4w==",
+ "dev": true,
+ "requires": {
+ "clone-deep": "4.0.1",
+ "loader-utils": "1.2.3",
+ "neo-async": "2.6.1",
+ "schema-utils": "2.5.0",
+ "semver": "6.3.0"
+ },
+ "dependencies": {
+ "schema-utils": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz",
+ "integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==",
+ "dev": true,
+ "requires": {
+ "ajv": "6.10.2",
+ "ajv-keywords": "3.4.1"
+ }
+ }
+ }
+ },
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
@@ -7755,6 +8199,15 @@
"safe-buffer": "5.1.2"
}
},
+ "shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -8517,6 +8970,12 @@
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
"dev": true
},
+ "type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+ "dev": true
+ },
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -8846,6 +9305,16 @@
"loader-utils": "1.2.3"
}
},
+ "vue-template-compiler": {
+ "version": "2.6.10",
+ "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz",
+ "integrity": "sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==",
+ "dev": true,
+ "requires": {
+ "de-indent": "1.0.2",
+ "he": "1.2.0"
+ }
+ },
"vue-template-es2015-compiler": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz",
diff --git a/app/themes/default/package.json b/app/themes/default/package.json
index a2641f9..c247514 100644
--- a/app/themes/default/package.json
+++ b/app/themes/default/package.json
@@ -1,11 +1,23 @@
{
- "author": "Chris Kankiewicz",
- "license": "MIT",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "devDependencies": {
- "laravel-mix": "^5.0.0",
- "tailwindcss": "^1.1.3"
- }
+ "author": "Chris Kankiewicz",
+ "license": "MIT",
+ "scripts": {
+ "dev": "npm run development",
+ "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
+ "watch": "npm run development -- --watch",
+ "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
+ "prod": "npm run production",
+ "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
+ },
+ "devDependencies": {
+ "@fortawesome/fontawesome-free": "^5.11.2",
+ "cross-env": "^6.0.3",
+ "laravel-mix": "^5.0.0",
+ "laravel-mix-purgecss": "^4.2.0",
+ "resolve-url-loader": "^3.1.0",
+ "sass": "^1.23.2",
+ "sass-loader": "^8.0.0",
+ "tailwindcss": "^1.1.3",
+ "vue-template-compiler": "^2.6.10"
+ }
}
diff --git a/app/themes/default/src/js/app.js b/app/themes/default/src/js/app.js
new file mode 100644
index 0000000..e69de29
diff --git a/app/themes/default/src/sass/app.scss b/app/themes/default/src/sass/app.scss
new file mode 100644
index 0000000..b5c61c9
--- /dev/null
+++ b/app/themes/default/src/sass/app.scss
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/app/themes/default/tailwind.config.js b/app/themes/default/tailwind.config.js
new file mode 100644
index 0000000..dd6532c
--- /dev/null
+++ b/app/themes/default/tailwind.config.js
@@ -0,0 +1,7 @@
+module.exports = {
+ theme: {
+ extend: {}
+ },
+ variants: {},
+ plugins: []
+}
diff --git a/app/themes/default/webpack.mix.js b/app/themes/default/webpack.mix.js
new file mode 100644
index 0000000..b186856
--- /dev/null
+++ b/app/themes/default/webpack.mix.js
@@ -0,0 +1,17 @@
+let mix = require('laravel-mix');
+let tailwindcss = require('tailwindcss');
+require('laravel-mix-purgecss');
+
+mix.sass('src/sass/app.scss', 'dist').options({
+ processCssUrls: false,
+ postCss: [tailwindcss('tailwind.config.js')]
+});
+
+mix.js('src/js/app.js', 'dist');
+
+mix.purgeCss({
+ extensions: ['html', 'scss', 'twig'],
+ globs: ['*.twig'],
+ folders: ['src'],
+ whitelist: ['html', 'body', 'main']
+});
diff --git a/index.php b/index.php
index ad2e3d1..3ba7f0c 100644
--- a/index.php
+++ b/index.php
@@ -1,18 +1,55 @@
set(Twig::class, new Twig('app/themes/default', ['cache' => 'app/cache']));
+/** Initialize environment variable handler */
+$dotenv = Dotenv::create(__DIR__);
+$dotenv->load();
+/** Create the container */
+$container = new Container();
+$container->set(Config::class, $config = new Config('app/config'));
+
+/** Set up our view handler */
+$twig = new Twig("app/themes/{$config->get('theme')}", [
+ 'cache' => $config->get('view_cache')
+]);
+
+$twig->getEnvironment()->getExtension(CoreExtension::class)->setDateFormat(
+ $config->get('date_format'), '%d days'
+);
+
+$twig->getEnvironment()->addFunction(
+ new TwigFunction('asset', function ($path) use ($config) {
+ return "/app/themes/{$config->get('theme')}/{$path}";
+ })
+);
+
+$twig->getEnvironment()->addFunction(
+ new TwigFunction('convertSize', function ($bytes) {
+ $sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+ $factor = floor((strlen($bytes) - 1) / 3);
+
+ return sprintf('%.2f', $bytes / pow(1024, $factor)) . $sizes[$factor];
+ })
+);
+
+$container->set(Twig::class, $twig);
+
+/** Create the application */
$app = Bridge::create($container);
$app->add(TwigMiddleware::createFromContainer($app, Twig::class));
$app->get('/[{path:.*}]', Controllers\DirectoryController::class);
+/** Enagage! */
$app->run();