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); } }
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; }
/** * 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; }
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); } } }
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; }