diff --git a/Controller/StaticController.php b/Controller/StaticController.php index e452781..173738a 100755 --- a/Controller/StaticController.php +++ b/Controller/StaticController.php @@ -32,43 +32,50 @@ class StaticController extends Controller { */ public function rootAction() { return $this->render('@GradientzTwigExpress/root.html.twig', [ - 'bundles' => Utils::getStaticBundles($this->container) + 'bundles' => $this->getParameter('twig_express.bundles') ]); } - /** - * Find a template to render or a folder whose content to list - * @param string $bundle - * @param string $path - * @return RedirectResponse|Response - */ - public function findAction($bundle, $path) { + /** + * Find a template to render or a folder whose content to list + * @param string $slug Slug identifying a bundle + * @param string $path Path to a resource (starting with '/') + * @return RedirectResponse|Response + * @throws \Exception + */ + public function findAction($slug, $path) { $cleanPath = Utils::getCleanPath($path); - $cleanRef = preg_replace('/(_|bundle$)/', '', strtolower($bundle)); $pathExt = pathinfo($cleanPath, PATHINFO_EXTENSION); $showSource = $pathExt === 'twig'; // Base URL for redirects and breadcrumbs (no trailing slash) $this->baseUrl = $this->generateUrl('gradientz_twig_express_find', [ - 'bundle' => $cleanRef, + 'slug' => $slug, 'path' => '' ]); // Redirect if we can clean up the URL - if ($cleanRef !== $bundle || $cleanPath !== $path) { + if ($cleanPath !== $path) { return $this->redirect($this->baseUrl . $cleanPath); } - // Figure out bundle name and path - $this->bundleName = Utils::findStaticBundle($this->container, $cleanRef); - if (!$this->bundleName) { + // Figure out bundle name + $bundleConfig = $this->getParameter('twig_express.bundles'); + if (!array_key_exists($slug, $bundleConfig)) { $rootUrl = $this->generateUrl('gradientz_twig_express_root'); - return $this->redirect($rootUrl . '?was=' . $cleanRef); + return $this->redirect($rootUrl . '?was=' . $slug); } - $this->bundlePath = rtrim($this->container->get('kernel')->locateResource('@'.$this->bundleName), '/'); + $this->bundleName = $bundleConfig[$slug]['name']; + + // Check that it's a valid bundle + $allBundles = array_keys($this->get('kernel')->getBundles()); + if (!in_array($this->bundleName, $allBundles)) { + throw new \Exception('Unknown bundle "'.$this->bundleName.'". Make sur this bundle is installed and your "twig_express.bundles" config is correct.'); + } // Where is our "document root"? - $docRoot = trim(Utils::VIEWS_ROOT, '/'); + $docRoot = $bundleConfig[$slug]['root']; + $this->bundlePath = rtrim($this->container->get('kernel')->locateResource('@'.$this->bundleName), '/'); $this->docRootName = '@'.$this->bundleName . '/' . $docRoot; $this->docRootPath = $this->bundlePath . '/' . $docRoot; $basePath = $this->docRootPath . rtrim($cleanPath, '/'); diff --git a/Core/Utils.php b/Core/Utils.php index 6a99002..e96483c 100644 --- a/Core/Utils.php +++ b/Core/Utils.php @@ -8,9 +8,6 @@ class Utils { - // TODO: replace this path with per-bundle, user-defined configuration - const VIEWS_ROOT = 'Resources/views/static'; - /** * Cleans up a local resource path, removing back-slashes, double dots, etc. * Should not be necessary for content from a URL but let's be on the safe side. @@ -48,44 +45,6 @@ static function getMediaType($ext) { return $type; } - /** - * List Assetic bundles that have a 'static' views folder - * @param ContainerInterface $container - * @return array|string - */ - static function getStaticBundles($container) { - $matched = []; - $fs = new Filesystem(); - $htmlPath = self::VIEWS_ROOT; - $bundles = $container->getParameter('assetic.bundles'); - - foreach ($bundles as $name) { - $bundlePath = $container->get('kernel')->locateResource('@' . $name); - if ($fs->exists($bundlePath . $htmlPath)) { - $matched[] = $name; - } - } - - return $matched; - } - - /** - * Find a bundle with 'static' views, matching a case-insensitive string, - * and return the bundle's name - * @param ContainerInterface $container - * @param string $shortName - partial bundle name to match - * @return string|null - */ - static function findStaticBundle($container, $shortName) { - $bundles = self::getStaticBundles($container); - foreach ($bundles as $name) { - if (strtolower($shortName) . 'bundle' === strtolower($name)) { - return $name; - } - } - return null; - } - /** * Make an associative array with URL=>Name values * representing the breadcrumbs for a given base URL and path diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php new file mode 100644 index 0000000..7dae413 --- /dev/null +++ b/DependencyInjection/Configuration.php @@ -0,0 +1,41 @@ +root('twig_express') + ->children() + ->arrayNode('bundles') + ->info('List of enabled bundles, with optional per-bundle config') + ->prototype('array') + ->beforeNormalization() + ->ifString()->then(function($v) { return ['name' => $v]; }) + ->end() + ->children() + ->scalarNode('name') + ->info('Bundle name') + ->isRequired() + ->end() + ->scalarNode('slug') + ->info('Short name to use in the URL') + ->defaultValue(null) + ->end() + ->scalarNode('root') + ->info('Document root folder from the bundle') + ->defaultValue('Resources/views/static') + ->end() + ->end() + ->end() + ->end() + ->end(); + return $treeBuilder; + } + +} diff --git a/DependencyInjection/GradientzTwigExpressExtension.php b/DependencyInjection/GradientzTwigExpressExtension.php new file mode 100644 index 0000000..6faf3fe --- /dev/null +++ b/DependencyInjection/GradientzTwigExpressExtension.php @@ -0,0 +1,43 @@ +processConfiguration(new Configuration(), $configs); + + // Make sure we have a base_url parameter so we can use it in routes + $baseUrl = $container->getParameter('twig_express.base_url'); + if (is_string($baseUrl)) $baseUrl = trim($baseUrl, '/'); + if (!$baseUrl) $container->setParameter('twig_express.base_url', 'static'); + + // Expose configured bundle information + // (Is there a better way to get access to our config from controllers???) + $bundles = []; + foreach($config['bundles'] as $item) { + $name = $item['name']; + $slug = $item['slug']; + // Create slug if necessary, and clean it up + if (!$slug) { + $slug = strtolower($name); + if (substr($slug, -6) === 'bundle') $slug = substr($slug, 0, -6); + } + $slug = str_replace('/', '', $slug); + $root = trim($item['root'], '/'); + if (!array_key_exists($slug, $bundles)) { + $bundles[$slug] = ['name' => $name, 'root' => $root]; + } + } + $container->setParameter('twig_express.bundles', $bundles); + } + +} diff --git a/GradientzTwigExpressBundle.php b/GradientzTwigExpressBundle.php index ccef237..972fba1 100755 --- a/GradientzTwigExpressBundle.php +++ b/GradientzTwigExpressBundle.php @@ -4,4 +4,10 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; -class GradientzTwigExpressBundle extends Bundle {} +class GradientzTwigExpressBundle extends Bundle { + + public function getContainerExtension() { + return new DependencyInjection\GradientzTwigExpressExtension(); + } + +} diff --git a/Resources/config/demo.yml b/Resources/config/demo.yml index e2a8528..34e5f72 100644 --- a/Resources/config/demo.yml +++ b/Resources/config/demo.yml @@ -1,10 +1,13 @@ -# Enable bundle for Assetic and GradientzTwigExpressBundle use -assetic: - bundles: [ GradientzTwigExpressBundle ] +# REQUIRED: enable this bundle to be used with GradientzTwigExpressBundle +twig_express: + bundles: + - name: GradientzTwigExpressBundle + slug: twig-express-demo + root: Resources/views/demo # (Optional) Add to Twig global variables, using a namespace to avoid collisions # (especially if you have more than one bundle with 'static' views). twig: globals: - gradientz_twig_express: + twig_express_demo: test: 'It works.' diff --git a/Resources/config/routing.yml b/Resources/config/routing.yml index 5a81300..494558d 100755 --- a/Resources/config/routing.yml +++ b/Resources/config/routing.yml @@ -1,12 +1,12 @@ gradientz_twig_express_root: - path: "/static/" + path: "/%twig_express.base_url%/" defaults: _controller: GradientzTwigExpressBundle:Static:root gradientz_twig_express_find: - path: "/static/{bundle}{path}" + path: "/%twig_express.base_url%/{slug}{path}" defaults: _controller: GradientzTwigExpressBundle:Static:find requirements: - bundle: "[A-Za-z0-9_]+" + slug: "[A-Za-z0-9_-]+" path: "(\\/?[\\/\\.A-Za-z0-9_-]+)?" diff --git a/Resources/views/static/1-simple-demo.html.twig b/Resources/views/demo/basic-demo.html.twig similarity index 88% rename from Resources/views/static/1-simple-demo.html.twig rename to Resources/views/demo/basic-demo.html.twig index 8f949f7..d198c00 100644 --- a/Resources/views/static/1-simple-demo.html.twig +++ b/Resources/views/demo/basic-demo.html.twig @@ -25,9 +25,9 @@
This config file can also be used to declare global Twig variables. For instance,
- this is the gradientz_twig_express.test
variable:
+ this is the twig_express_demo.test
variable:
{{ gradientz_twig_express.test }}+
{{ twig_express_demo.test }}{% endblock %}