public function formatContents(array $rawSegments)
 {
     try {
         return $this->formatContentsUnsafe($rawSegments);
     } catch (Exception $e) {
         $relativePath = PageHelper::getRelativePath($this->page);
         throw new PieCrustException("Error formatting page '{$relativePath}': {$e->getMessage()}", 0, $e);
     }
 }
Beispiel #2
0
 public function testGetSimpleSitePages()
 {
     $fs = MockFileSystem::create()->withPage('_index', array(), 'Blah.');
     $app = $fs->getApp();
     $pages = $app->getEnvironment()->getPages();
     $this->assertEquals(1, count($pages));
     $this->assertEquals('_index.html', PageHelper::getRelativePath($pages[0]));
     $this->assertEquals(str_replace('\\', '/', $fs->url('kitchen/_content/pages/_index.html')), str_replace('\\', '/', $pages[0]->getPath()));
 }
 protected function bakePage(IPage $page)
 {
     $start = microtime(true);
     $baker = new PageBaker($this->getBakeDir(), $this->getPageBakerParameters(), $this->logger);
     $didBake = $baker->bake($page);
     if (!$didBake) {
         return;
     }
     if ($baker->wasPaginationDataAccessed()) {
         $relativePath = PageHelper::getRelativePath($page);
         $this->bakeRecord->addPageUsingPosts($relativePath);
     }
     $pageCount = $baker->getPageCount();
     $this->logger->info(self::formatTimed($start, ($page->getUri() == '' ? '[main page]' : $page->getUri()) . ($pageCount > 1 ? " [{$pageCount}]" : "")));
     return true;
 }
Beispiel #4
0
 /**
  * Bakes the given page. Additional template data can be provided, along with
  * a specific set of posts for the pagination data.
  */
 public function bake(IPage $page, array $extraData = null)
 {
     $didBake = false;
     try {
         $this->bakedFiles = array();
         $this->paginationDataAccessed = false;
         $this->logger->debug("Baking '{$page->getUri()}'...");
         $pageRenderer = new PageRenderer($page);
         $hasMorePages = true;
         while ($hasMorePages) {
             $didBakeThisOne = $this->bakeSinglePage($pageRenderer, $extraData);
             $didBake |= $didBakeThisOne;
             if (!$didBakeThisOne) {
                 break;
             }
             $data = $page->getPageData();
             if ($data and isset($data['pagination'])) {
                 $paginator = $data['pagination'];
                 $hasMorePages = ($paginator->wasPaginationDataAccessed() and $paginator->hasMorePages());
                 if ($hasMorePages) {
                     $page->setPageNumber($page->getPageNumber() + 1);
                     // setPageNumber() resets the page's data, so when we
                     // enter bakeSinglePage again in the next loop, we have
                     // to re-set the extraData and all other stuff.
                 }
             }
         }
     } catch (Exception $e) {
         $pageRelativePath = PageHelper::getRelativePath($page);
         throw new PieCrustException("Error baking page '{$pageRelativePath}' (p{$page->getPageNumber()})", 0, $e);
     }
     // Record our work.
     if ($this->bakeRecord) {
         $this->bakeRecord->addPageEntry($page, $didBake ? $this : null);
     }
     return $didBake;
 }
Beispiel #5
0
 protected function ensureLinksCache()
 {
     if ($this->linksCache === null) {
         try {
             $pieCrust = $this->page->getApp();
             $pageRepository = $pieCrust->getEnvironment()->getPageRepository();
             $this->linksCache = array();
             $skipNames = array('Thumbs.db');
             $it = new FilesystemIterator($this->baseDir);
             foreach ($it as $item) {
                 $basename = $item->getBasename();
                 // Skip dot files, Thumbs.db, etc.
                 if (!$basename or $basename[0] == '.') {
                     continue;
                 }
                 if (in_array($item->getFilename(), $skipNames)) {
                     continue;
                 }
                 if ($item->isDir()) {
                     $linker = new Linker($this->page, $item->getPathname());
                     $this->linksCache[$basename . '_'] = $linker;
                     // We add '_' at the end of the directory name to avoid
                     // collisions with a possibly existing page with the same
                     // name (since we strip out the '.html' extension).
                     // This means the user must access directories with
                     // 'link.dirname_' instead of 'link.dirname' but hey, if
                     // you have a better idea, send me an email!
                 } else {
                     $path = $item->getPathname();
                     try {
                         $relativePath = PageHelper::getRelativePath($this->page);
                         $uri = UriBuilder::buildUri($relativePath);
                         // To get the link's page, we need to be careful with the case
                         // where that page is the currently rendering one. This is
                         // because it could be rendering a sub-page -- but we would be
                         // requesting the default first page, which would effectively
                         // change the page number *while* we're rendering, which leads
                         // to all kinds of bad things!
                         // TODO: obviously, there needs to be some design changes to
                         // prevent this kind of chaotic behaviour.
                         if ($path == $this->page->getPath()) {
                             $page = $this->page;
                         } else {
                             $page = $pageRepository->getOrCreatePage($uri, $path);
                         }
                         $key = str_replace('.', '_', $item->getBasename('.html'));
                         $this->linksCache[$key] = array('uri' => $uri, 'name' => $key, 'is_dir' => false, 'is_self' => $basename == $this->selfName, 'page' => new PaginationData($page));
                     } catch (Exception $e) {
                         throw new PieCrustException("Error while loading page '{$path}' for linking from '{$this->page->getUri()}': " . $e->getMessage(), 0, $e);
                     }
                 }
             }
             if ($this->sortByName) {
                 if (false === usort($this->linksCache, array($this, 'sortByCustom'))) {
                     throw new PieCrustException("Error while sorting pages with the specified setting: {$this->sortByName}");
                 }
             }
             if ($this->selfName != null) {
                 // Add special stuff only for the original Linker
                 // (the one directly created by the current page).
                 if (PageHelper::isRegular($this->page)) {
                     // Add a link to go up to the parent directory, but stay inside
                     // the app's pages directory.
                     $parentBaseDir = dirname($this->baseDir);
                     if (strlen($parentBaseDir) >= strlen($pieCrust->getPagesDir())) {
                         $linker = new Linker($this->page, dirname($this->baseDir));
                         $this->linksCache['_'] = $linker;
                     }
                 } else {
                     if (PageHelper::isPost($this->page)) {
                         // Add a link to go up to the parent directory, but stay inside
                         // the app's posts directory.
                         $parentBaseDir = dirname($this->baseDir);
                         if (strlen($parentBaseDir) >= strlen($pieCrust->getPostsDir())) {
                             $linker = new Linker($this->page, dirname($this->baseDir));
                             $this->linksCache['_'] = $linker;
                         }
                     }
                 }
                 if ($pieCrust->getPagesDir()) {
                     // Add a shortcut to the pages directory.
                     $linker = new Linker($this->page, $pieCrust->getPagesDir());
                     $this->linksCache['_pages_'] = $linker;
                 }
                 if ($pieCrust->getPostsDir()) {
                     // Add a shortcut to the posts directory.
                     $linker = new Linker($this->page, $pieCrust->getPostsDir());
                     $this->linksCache['_posts_'] = $linker;
                 }
             }
         } catch (Exception $e) {
             throw new PieCrustException("Error while building the links from page '{$this->page->getUri()}': " . $e->getMessage(), 0, $e);
         }
     }
 }
Beispiel #6
0
 protected function bakeSinglePage(PageRenderer $pageRenderer, array $extraData = null)
 {
     $page = $pageRenderer->getPage();
     // Set the extra template data before the page's data is computed.
     if ($extraData != null) {
         $page->setExtraPageData($extraData);
     }
     // This is usually done in the PieCrustBaker, but we'll do it here too
     // because the `PageBaker` could be used on its own.
     if ($this->parameters['copy_assets']) {
         $page->setAssetUrlBaseRemap("%site_root%%uri%");
     }
     // Figure out the output HTML path.
     $bakePath = $this->getOutputPath($page);
     // Figure out if we should re-bake this page.
     $doBake = true;
     if (is_file($bakePath) && $this->parameters['smart']) {
         // Don't rebake if the output seems up-to-date, and
         // the page isn't known to be using posts.
         if (filemtime($page->getPath()) < filemtime($bakePath)) {
             $bakeRecord = $this->parameters['bake_record'];
             if ($bakeRecord) {
                 $relativePath = PageHelper::getRelativePath($page);
                 if (!$bakeRecord->wasAnyPostBaked() || !$bakeRecord->isPageUsingPosts($relativePath)) {
                     $doBake = false;
                 }
             }
         }
     }
     if (!$doBake) {
         $this->logger->debug("Not baking '{$page->getUri()}/{$page->getPageNumber()}' because '{$bakePath}' is up-to-date.");
         return false;
     }
     // Backward compatibility warning and file-copy.
     // [TODO] Remove in a couple of versions.
     $copyToOldPath = false;
     $contentType = $page->getConfig()->getValue('content_type');
     $nativeExtension = pathinfo($page->getPath(), PATHINFO_EXTENSION);
     if ($contentType != 'html' && $nativeExtension == 'html') {
         $copyToOldPath = $this->bakeDir . $page->getUri();
         if ($page->getPageNumber() > 1) {
             $copyToOldPath .= $page->getPageNumber() . '/';
         }
         $copyToOldPath .= '.' . $contentType;
     }
     // If we're using portable URLs, change the site root to a relative
     // path from the page's directory.
     $savedSiteRoot = $this->setPortableSiteRoot($page->getApp(), $bakePath);
     // Render the page.
     $bakedContents = $pageRenderer->get();
     // Get some objects we need.
     $data = $page->getPageData();
     $assetor = $data['asset'];
     $paginator = $data['pagination'];
     // Copy the page.
     PathHelper::ensureDirectory(dirname($bakePath));
     file_put_contents($bakePath, $bakedContents);
     $this->bakedFiles[] = $bakePath;
     // [TODO] See previous TODO.
     if ($copyToOldPath) {
         $this->logger->warning("Page '{$page->getUri()}' has 'content_type' specified but is an HTML file.");
         $this->logger->warning("Changing a baked file's extension using 'content_type' is deprecated and will be removed in a future version.");
         $this->logger->warning("For backwards compatibility, the page will also be baked to: " . substr($copyToOldPath, strlen($this->bakeDir)));
         $this->logger->warning("To fix the problem, change the source file's extension to the desired output extension.");
         $this->logger->warning("Otherwise, just ignore these messages.");
         file_put_contents($copyToOldPath, $bakedContents);
     }
     // Copy any used assets for the first sub-page.
     if ($page->getPageNumber() == 1 and $this->parameters['copy_assets']) {
         $prettyUrls = PageHelper::getConfigValue($page, 'pretty_urls', 'site');
         if ($prettyUrls) {
             $bakeAssetDir = dirname($bakePath) . '/';
         } else {
             $bakePathInfo = pathinfo($bakePath);
             $bakeAssetDir = $bakePathInfo['dirname'] . '/' . ($page->getUri() == '' ? '' : $bakePathInfo['filename']) . '/';
         }
         $assetPaths = $assetor->getAssetPathnames();
         if ($assetPaths != null) {
             PathHelper::ensureDirectory($bakeAssetDir);
             foreach ($assetPaths as $assetPath) {
                 $destinationAssetPath = $bakeAssetDir . basename($assetPath);
                 if (@copy($assetPath, $destinationAssetPath) == false) {
                     throw new PieCrustException("Can't copy '" . $assetPath . "' to '" . $destinationAssetPath . "'.");
                 }
             }
         }
     }
     // Remember a few things.
     $this->paginationDataAccessed = ($this->paginationDataAccessed or $paginator->wasPaginationDataAccessed());
     // Cleanup.
     if ($savedSiteRoot) {
         $page->getApp()->getConfig()->setValue('site/root', $savedSiteRoot);
     }
     return true;
 }