+
+       /**
+        * The directory page
+        *
+        * Display directory
+        *
+        * @param Request $request The request instance
+        * @param string $path The directory path
+        * @return Response The rendered view
+        */
+       public function directory(Request $request, string $path): Response {
+               header('Content-Type: text/plain');
+               var_dump($path);
+               exit;
+
+               //Render template
+               $response = $this->render('@RapsysTree/directory.html.twig', $this->context);
+
+               $response->setEtag(md5($response->getContent()));
+               $response->setPublic();
+               $response->isNotModified($request);
+
+               //Return response
+               return $response;
+       }
+
+       /**
+        * The document page
+        *
+        * Display document
+        *
+        * @param Request $request The request instance
+        * @param string $path The directory path
+        * @return Response The rendered view
+        */
+       public function document(Request $request, string $path): Response {
+               //Render template
+               $response = $this->render('@RapsysTree/document.html.twig', $this->context);
+
+               $response->setEtag(md5($response->getContent()));
+               $response->setPublic();
+               $response->isNotModified($request);
+
+               //Return response
+               return $response;
+       }
+
+       /**
+        * Renders a view
+        *
+        * {@inheritdoc}
+        */
+       protected function render(string $view, array $parameters = [], Response $response = null): Response {
+               //Create response when null
+               $response ??= new Response();
+
+               //Without alternates
+               if (count($parameters['alternates']) <= 1) {
+                       //Set routeParams
+                       $routeParams = $this->routeParams;
+
+                       //Iterate on locales excluding current one
+                       foreach($this->config['locales'] as $locale) {
+                               //With current locale
+                               if ($locale !== $this->locale) {
+                                       //Set titles
+                                       $titles = [];
+
+                                       //Set route params locale
+                                       $routeParams['_locale'] = $locale;
+
+                                       //Iterate on other locales
+                                       foreach(array_diff($this->config['locales'], [$locale]) as $other) {
+                                               //Set other locale title
+                                               $titles[$other] = $this->translator->trans($this->config['languages'][$locale], [], null, $other);
+                                       }
+
+                                       //Set locale locales context
+                                       $parameters['alternates'][str_replace('_', '-', $locale)] = [
+                                               'absolute' => $this->router->generate($this->route, $routeParams, UrlGeneratorInterface::ABSOLUTE_URL),
+                                               'relative' => $this->router->generate($this->route, $routeParams),
+                                               'title' => implode('/', $titles),
+                                               'translated' => $this->translator->trans($this->config['languages'][$locale], [], null, $locale)
+                                       ];
+
+                                       //Add shorter locale
+                                       if (empty($parameters['alternates'][$shortCurrent = substr($locale, 0, 2)])) {
+                                               //Set locale locales context
+                                               $parameters['alternates'][$shortCurrent] = $parameters['alternates'][str_replace('_', '-', $locale)];
+                                       }
+                               }
+                       }
+               }
+
+               //With canonical
+               if (!empty($parameters['canonical'])) {
+                       //Set facebook url
+                       $parameters['facebook']['og:url'] = $parameters['canonical'];
+               }
+
+               //With empty facebook title and title
+               if (empty($parameters['facebook']['og:title']) && !empty($parameters['title']['page'])) {
+                       //Set facebook title
+                       $parameters['facebook']['og:title'] = $parameters['title']['page'];
+               }
+
+               //With empty facebook description and description
+               if (empty($parameters['facebook']['og:description']) && !empty($parameters['description'])) {
+                       //Set facebook description
+                       $parameters['facebook']['og:description'] = $parameters['description'];
+               }
+
+               //With locale
+               if (!empty($this->locale)) {
+                       //Set facebook locale
+                       $parameters['facebook']['og:locale'] = $this->locale;
+
+                       //With alternates
+                       //XXX: locale change when fb_locale=xx_xx is provided is done in FacebookSubscriber
+                       //XXX: see https://stackoverflow.com/questions/20827882/in-open-graph-markup-whats-the-use-of-oglocalealternate-without-the-locati
+                       if (!empty($parameters['alternates'])) {
+                               //Iterate on alternates
+                               foreach($parameters['alternates'] as $lang => $alternate) {
+                                       if (strlen($lang) == 5) {
+                                               //Set facebook locale alternate
+                                               $parameters['facebook']['og:locale:alternate'] = str_replace('-', '_', $lang);
+                                       }
+                               }
+                       }
+               }
+
+               //Without facebook image defined and texts
+               if (empty($parameters['facebook']['og:image']) && !empty($this->request) && !empty($parameters['fbimage']['texts']) && !empty($this->modified)) {
+                       //Get facebook image
+                       $parameters['facebook'] += $this->facebook->getImage($this->request->getPathInfo(), $parameters['fbimage']['texts'], $this->modified->getTimestamp());
+               }
+
+               //Call twig render method
+               $content = $this->twig->render($view, $parameters);
+
+               //Invalidate OK response on invalid form
+               if (200 === $response->getStatusCode()) {
+                       foreach ($parameters as $v) {
+                               if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) {
+                                       $response->setStatusCode(422);
+                                       break;
+                               }
+                       }
+               }
+
+               //Store content in response
+               $response->setContent($content);
+
+               //Return response
+               return $response;
+       }