Skip to content

Commit

Permalink
Close #3 - only show Twig source if in debug mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Florens Verschelde committed Sep 23, 2016
1 parent 4fc2cd9 commit 3c8e9bc
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 102 deletions.
199 changes: 106 additions & 93 deletions Controller/StaticController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class StaticController extends Controller {

// The excution flow can go e.g.: findAction -> renderTwig -> showTwigError,
// and we'd like to keep some information around.
/** @var bool The kernel.debug parameter */
protected $debug;
/** @var string Base URL for a request, e.g. '/static/bundleref/' */
protected $baseUrl;
/** @var null|string Valid bundle name, e.g. 'SomeCoolBundle' */
Expand Down Expand Up @@ -44,7 +46,8 @@ public function rootAction() {
* @throws \Exception
*/
public function findAction($slug, $path) {
$cleanPath = Utils::getCleanPath($path);
$this->debug = $this->getParameter('kernel.debug');
$cleanPath = Utils::getCleanPath($path);
$pathExt = pathinfo($cleanPath, PATHINFO_EXTENSION);
$showSource = $pathExt === 'twig';

Expand All @@ -55,25 +58,30 @@ public function findAction($slug, $path) {
]);

// Redirect if we can clean up the URL
if ($cleanPath !== $path) {
if ($cleanPath !== $path) {
return $this->redirect($this->baseUrl . $cleanPath);
}
}

// Redirect if URL asks for a Twig file but we’re not in debug mode
if (!$this->debug && substr($cleanPath, -5) === '.twig') {
return $this->redirect($this->baseUrl . substr($cleanPath, 0, -5));
}

// Figure out bundle name
// 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=' . $slug);
}
$rootUrl = $this->generateUrl('gradientz_twig_express_root');
return $this->redirect($rootUrl . '?was=' . $slug);
}
$this->bundleName = $bundleConfig[$slug]['name'];

// Check that it's a valid bundle
// 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.');
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"?
// Where is our "document root"?
$docRoot = $bundleConfig[$slug]['root'];
$this->bundlePath = rtrim($this->container->get('kernel')->locateResource('@'.$this->bundleName), '/');
$this->docRootName = '@'.$this->bundleName . '/' . $docRoot;
Expand Down Expand Up @@ -110,108 +118,113 @@ public function findAction($slug, $path) {
return $this->render404($cleanPath);
}

/**
* Show a directory listing page
* @param string $dirPath Directory system path
/**
* Show a directory listing page
* @param string $dirPath Directory system path
* @param string $urlFragment URL without base or bundle key
* @return Response
*/
private function renderDir($dirPath, $urlFragment) {
* @return Response
*/
private function renderDir($dirPath, $urlFragment) {
// Prepare breadcrumbs
$breadcrumbs = Utils::makeBreadcrumbs(
$this->baseUrl,
$this->bundleName,
$urlFragment
);

// Prepare content list
$finder = new Finder();
$iterator = $finder->depth(0)->in($dirPath)->sortByName();
$dirList = [];
$fileList = [];
foreach ($iterator->directories() as $dir) {
// Prepare content list
$finder = new Finder();
$iterator = $finder->depth(0)->in($dirPath)->sortByName();
$dirList = [];
$fileList = [];
foreach ($iterator->directories() as $dir) {
$dirList[] = $dir->getFilename();
}
foreach ($iterator->files()->name('*.twig') as $file) {
}
foreach ($iterator->files()->name('*.twig') as $file) {
$fileList[] = str_replace('.twig', '', $file->getFilename());
}
}

return $this->render('@GradientzTwigExpress/dir.html.twig', [
'crumbs' => $breadcrumbs,
'dirList' => $dirList,
'fileList' => $fileList
]);
}
return $this->render('@GradientzTwigExpress/dir.html.twig', [
'crumbs' => $breadcrumbs,
'dirList' => $dirList,
'fileList' => $fileList
]);
}

/**
* Show a File Not Found page
/**
* Show a File Not Found page
* @param string $urlFragment URL without base or bundle key
* @return Response
*/
private function render404($urlFragment) {
// Prepare breadcrumbs
* @return Response
*/
private function render404($urlFragment) {
// Prepare breadcrumbs
$breadcrumbs = Utils::makeBreadcrumbs(
$this->baseUrl,
$this->bundleName,
$urlFragment
);

// Prepare message
// Prepare message
$root = $this->docRootName;
if (substr($urlFragment, -5) === '.twig' || substr($urlFragment, -1) === '/') {
$miss = $urlFragment;
} else {
$miss = $urlFragment . '.twig';
}
$message = '<p>Could not find : <code class="error">'.$miss.'</code><br>';
$message .= "\nIn : <code>$root</code></p>";
$message = '<p>Could not find : <code class="error">'.$miss.'</code><br>';
$message .= "\nIn : <code>$root</code></p>";

$response = $this->render('@GradientzTwigExpress/page.html.twig', [
'crumbs' => $breadcrumbs,
$response = $this->render('@GradientzTwigExpress/page.html.twig', [
'crumbs' => $breadcrumbs,
'metaTitle' => 'Not found: ' . $urlFragment,
'title' => 'File does not exist',
'message' => $message
]);
$response->setStatusCode(404);
return $response;
}
'title' => 'File does not exist',
'message' => $message
]);
$response->setStatusCode(404);
return $response;
}

/**
* Render a Twig template
* @param string $templateName
* @return Response
*/
private function renderTwig($templateName) {
// Do we have an extension, like .html or .json?
$ext = pathinfo(substr($templateName, 0, -5), PATHINFO_EXTENSION);
/**
* Render a Twig template
* @param string $templateName
* @return Response
* @throws Twig_Error
*/
private function renderTwig($templateName) {
// Do we have an extension, like .html or .json?
$ext = pathinfo(substr($templateName, 0, -5), PATHINFO_EXTENSION);
$cType = $ext ? Utils::getMediaType($ext) . ';charset=utf-8' : null;
try {
$response = $this->render($templateName);
if ($cType) $response->headers->set('Content-Type', $cType);
return $response;
}
catch (Twig_Error $error) {
return $this->showTwigError($error, $templateName);
}
}
try {
$response = $this->render($templateName);
if ($cType) $response->headers->set('Content-Type', $cType);
return $response;
}
catch (Twig_Error $error) {
if ($this->debug) {
return $this->showTwigError($error, $templateName);
} else {
throw $error;
}
}
}

/**
* Show an error page for a Twig_Error, with the faulty Twig code if we can.
* @param Twig_Error $error
/**
* Show an error page for a Twig_Error, with the faulty Twig code if we can.
* @param Twig_Error $error
* @param string $templateName Path of rendered template (error may be in a different template)
* @return Response
*/
private function showTwigError(Twig_Error $error, $templateName) {
* @return Response
*/
private function showTwigError(Twig_Error $error, $templateName) {
$line = $error->getTemplateLine();
$message = $error->getRawMessage();

// Might be different from $templateName, if the error occurred in an
// Might be different from $templateName, if the error occurred in an
// included file. Also we can get one of three types of result:
// - A full system path
// - @SomeBundleNameBundle/some/path/xyz
// - @SomeBundleName/xyz (= @SomeBundleNameBundle/Resources/views/xyz)
// We're going to have to do a bit of guessing.
$fileRef = $error->getTemplateFile();
$fileRef = $error->getTemplateFile();
$filePath = $fileRef; // ultimately, we want a full system path
$fileName = $fileRef; // we want a @SomeBundleNameBundle/xyz type of name

Expand Down Expand Up @@ -241,45 +254,45 @@ private function showTwigError(Twig_Error $error, $templateName) {
str_replace($this->docRootName, '', $templateName)
);

$data = [
'metaTitle' => 'Error: ' . basename($fileName),
'title' => get_class($error),
'crumbs' => $breadcrumbs,
$data = [
'metaTitle' => 'Error: ' . basename($fileName),
'title' => get_class($error),
'crumbs' => $breadcrumbs,
'activeCrumb' => count($breadcrumbs) - 1,
'message' => "$message<br>\nLine $line of <code>$fileName</code>"
];
'message' => "$message<br>\nLine $line of <code>$fileName</code>"
];

// Get a few lines of code from the buggy template
if (file_exists($filePath)) {
if (file_exists($filePath)) {
$code = file_get_contents($filePath);
$data['code'] = Utils::formatCodeBlock($code, true, $line, 5);
$data['codeLang'] = Utils::getHighlightLanguage($fileRef);
}
}

return $this->render('@GradientzTwigExpress/page.html.twig', $data);
}

/**
* Show a Twig file with syntax highlighting
* @param string $systemPath Full path to file
/**
* Show a Twig file with syntax highlighting
* @param string $systemPath Full path to file
* @param string $urlFragment URL without base or bundle key
* @return Response
*/
private function showSource($systemPath, $urlFragment) {
*/
private function showSource($systemPath, $urlFragment) {
// Prepare breadcrumbs
$breadcrumbs = Utils::makeBreadcrumbs(
$this->baseUrl,
$this->bundleName,
$urlFragment
);
$code = file_get_contents($systemPath);
$data = [
'metaTitle' => 'Source: ' . basename($systemPath),
'crumbs' => $breadcrumbs,
'code' => Utils::formatCodeBlock($code, true),
$data = [
'metaTitle' => 'Source: ' . basename($systemPath),
'crumbs' => $breadcrumbs,
'code' => Utils::formatCodeBlock($code, true),
'codeLang' => Utils::getHighlightLanguage($systemPath)
];
];
return $this->render('@GradientzTwigExpress/page.html.twig', $data);
}
}

}
18 changes: 9 additions & 9 deletions Resources/public/demo/styles.css
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
body::after,
.test {
display: block;
margin: 1em 0;
padding: 2em 1em;
text-align: center;
color: white;
background: black;
display: block;
margin: 1em 0;
padding: 2em 1em;
text-align: center;
color: white;
background: black;
}

body::after {
content: "Stylesheet 1/1 is loaded";
background: blue;
content: "Stylesheet 1/1 is loaded";
background: blue;
}

.test {
background: green;
background: green;
}

0 comments on commit 3c8e9bc

Please sign in to comment.