/** * @dataProvider renderTemplateDataProvider */ public function testTemplateRendering($testFilename, $expectedResultsFilename) { // Render our template. $fs = MockFileSystem::create()->withPagesDir(); $pc = $fs->getApp(array('cache' => false)); $pc->getConfig()->setValue('site/root', 'http://whatever/'); $pc->setTemplatesDirs(PIECRUST_UNITTESTS_DATA_DIR . 'templates'); $testInfo = pathinfo($testFilename); $engine = PieCrustHelper::getTemplateEngine($pc, $testInfo['extension']); $this->assertNotNull($engine, "Couldn't find a template engine for extension: " . $testInfo['extension']); $this->assertEquals($testInfo['extension'], $engine->getExtension()); ob_start(); try { $data = $pc->getConfig()->get(); $data['page'] = array('title' => 'The title of the page'); $engine->renderFile(array($testInfo['basename']), $data); } catch (Exception $e) { ob_end_clean(); throw $e; } $actualResults = ob_get_clean(); $actualResults = str_replace("\r\n", "\n", $actualResults); // Compare to what we are expecting. $expectedResults = file_get_contents($expectedResultsFilename); $expectedResults = str_replace("\r\n", "\n", $expectedResults); $this->assertEquals($expectedResults, $actualResults, 'The rendered template is not what we expected.'); }
private function addAutomaticLocations($sitemap, $xml) { if (!isset($sitemap['autogen'])) { return; } $autogen = $sitemap['autogen']; if (isset($autogen['pages']) && $autogen['pages']) { foreach ($this->pieCrust->getEnvironment()->getPages() as $page) { $xml->startElement('url'); $xml->writeElement('loc', PieCrustHelper::formatUri($this->pieCrust, $page->getUri())); $xml->writeElement('lastmod', date('c')); $xml->endElement(); } } if (isset($autogen['posts']) && $autogen['posts']) { $blogKeys = $this->pieCrust->getConfig()->getValueUnchecked('site/blogs'); foreach ($blogKeys as $blogKey) { foreach ($this->pieCrust->getEnvironment()->getPosts($blogKey) as $page) { $xml->startElement('url'); $xml->writeElement('loc', PieCrustHelper::formatUri($this->pieCrust, $page->getUri())); $xml->writeElement('lastmod', date('c')); $xml->endElement(); } } } }
/** * Renders the given page and sends the result to the standard output. */ public function render() { $pieCrust = $this->page->getApp(); $pageConfig = $this->page->getConfig(); // Get the template name. $templateName = $this->page->getConfig()->getValue('layout'); if ($templateName == null or $templateName == '' or $templateName == 'none') { $templateName = false; } else { if (!preg_match('/\\.[a-zA-Z0-9]+$/', $templateName)) { $templateName .= '.html'; } } if ($templateName !== false) { // Get the template engine and the page data. $extension = pathinfo($templateName, PATHINFO_EXTENSION); $templateEngine = PieCrustHelper::getTemplateEngine($pieCrust, $extension); // Render the page. $data = DataBuilder::getTemplateRenderingData($this->page); $templateEngine->renderFile($templateName, $data); } else { // No template... just output the 'content' segment. echo $this->page->getContentSegment(); } if ($pieCrust->isDebuggingEnabled()) { // Add a footer with version, caching and timing information. $this->renderStatsFooter($this->page); } }
/** * Renders the given page and sends the result to the standard output. */ public function render() { $pieCrust = $this->page->getApp(); $pageConfig = $this->page->getConfig(); // Set the page as the current context. $executionContext = $pieCrust->getEnvironment()->getExecutionContext(true); $executionContext->pushPage($this->page); // Get the template name. $templateNames = $this->page->getConfig()->getValue('layout'); if ($templateNames == null or $templateNames == '' or $templateNames == 'none') { $templateNames = false; } else { $templateNames = explode(',', $templateNames); foreach ($templateNames as &$name) { if (!preg_match('/\\.[a-zA-Z0-9]+$/', $name)) { $name .= '.html'; } } } if ($templateNames !== false) { // Get the template engine and the page data. $extension = pathinfo($templateNames[0], PATHINFO_EXTENSION); $templateEngine = PieCrustHelper::getTemplateEngine($pieCrust, $extension); // Render the page. $data = DataBuilder::getTemplateRenderingData($this->page); $templateEngine->renderFile($templateNames, $data); } else { // No template... just output the 'content' segment. echo $this->page->getContentSegment(); } // Restore the previous context. $executionContext->popPage(); }
/** * @dataProvider formatUriDataProviderWhenBaked */ public function testFormatUriWhenBaked($pageUri, $expectedUri, $siteRoot = '/', $prettyUrls = true, $debug = false, $trailingSlash = false) { $fs = MockFileSystem::create(); $fs->withConfig(array('site' => array('root' => $siteRoot, 'pretty_urls' => $prettyUrls), 'baker' => array('is_baking' => true, 'trailing_slash' => $trailingSlash))); $pc = new PieCrust(array('root' => $fs->getAppRoot(), 'cache' => false, 'debug' => $debug)); $uri = PieCrustHelper::formatUri($pc, $pageUri); $this->assertEquals($expectedUri, $uri); }
public function testSmartyPantsFormatter() { $fs = MockFileSystem::create()->withConfig(array('smartypants' => array('enabled' => true))); $app = $fs->getApp(); $text = PieCrustHelper::formatText($app, 'Something...'); $this->assertEquals("<p>Something…</p>\n", $text); // At the beginning you enabled SmartyPants with 'enable', and not 'enabled'. $fs = MockFileSystem::create()->withConfig(array('smartypants' => array('enable' => true))); $app = $fs->getApp(); $text = PieCrustHelper::formatText($app, 'Something...'); $this->assertEquals("<p>Something…</p>\n", $text); }
public function run(ChefContext $context) { $result = $context->getResult(); $app = $context->getApp(); $log = $context->getLog(); // Create the posts directory if it doesn't exist. if ($app->getPostsDir() == false) { $postsDir = $app->getRootDir() . PieCrustDefaults::CONTENT_POSTS_DIR; $log->info("Creating posts directory: {$postsDir}"); mkdir($postsDir, 0777, true); $app->setPostsDir($postsDir); } // Create the relative path of the new post by using the // path format of the website's post file-system. $slug = $result->command->command->args['slug']; $captureGroups = array('day' => date('d'), 'month' => date('m'), 'year' => date('Y'), 'slug' => $slug, 'ext' => 'html'); // Figure out which blog to create this post for (if the website // is hosting several blogs). $blogKey = $result->command->command->options['blog']; $blogKeys = $app->getConfig()->getValue('site/blogs'); if ($blogKey == null) { $blogKey = $blogKeys[0]; } else { if (!in_array($blogKey, $blogKeys)) { throw new PieCrustException("Specified blog '{$blogKey}' is not one of the known blogs in this website: " . implode(', ', $blogKeys)); } } // Create the full path. $fs = $app->getEnvironment()->getFileSystem(); $pathInfo = $fs->getPostPathInfo($blogKey, $captureGroups, FileSystem::PATHINFO_CREATING); $fullPath = $pathInfo['path']; $relativePath = PieCrustHelper::getRelativePath($app, $fullPath); if (file_exists($fullPath)) { throw new PieCrustException("Post already exists: {$relativePath}"); } $log->info("Creating new post: {$relativePath}"); // Create the title and time of post. $title = preg_replace('/[\\-_]+/', ' ', $slug); $title = ucwords($title); $time = date('H:i:s'); // Write the contents. if (!is_dir(dirname($fullPath))) { mkdir(dirname($fullPath), 0777, true); } $f = fopen($fullPath, 'w'); fwrite($f, "---\n"); fwrite($f, "title: {$title}\n"); fwrite($f, "time: {$time}\n"); fwrite($f, "---\n"); fwrite($f, "My new blog post!\n"); fclose($f); }
protected function addCustomValues() { $post = $this->page; $pieCrust = $this->page->getApp(); $blogKey = $this->page->getConfig()->getValueUnchecked('blog'); $postsDateFormat = PageHelper::getConfigValueUnchecked($this->page, 'date_format', $blogKey); // Add the easy values to the values array. $this->values['url'] = PieCrustHelper::formatUri($pieCrust, $post->getUri()); $this->values['slug'] = $post->getUri(); $this->values['timestamp'] = $post->getDate(); //TODO: do we need to move this to the lazy-loaded values? $this->values['date'] = date($postsDateFormat, $post->getDate()); // Add some lazy-loading functions for stuff // that would load the page's contents. $this->lazyValues[self::WILDCARD] = 'loadContent'; }
protected function addCustomValues() { $post = $this->page; $pieCrust = $post->getApp(); $blogKey = $post->getConfig()->getValueUnchecked('blog'); $postsDateFormat = PageHelper::getConfigValueUnchecked($post, 'date_format', $blogKey); // Add the easy values to the values array. $this->values['url'] = PieCrustHelper::formatUri($pieCrust, $post->getUri()); $this->values['slug'] = $post->getUri(); $this->values['timestamp'] = $post->getDate(true); $this->values['date'] = date($postsDateFormat, $post->getDate(true)); // Make it possible to access assets. $assetor = new Assetor($post); $this->values['assets'] = $assetor; // Add some lazy-loading functions for stuff // that would load the page's contents. $this->lazyValues[self::WILDCARD] = 'loadContent'; }
public function run(ChefContext $context) { $result = $context->getResult(); $app = $context->getApp(); $log = $context->getLog(); // Create the pages directory if it doesn't exist. if ($app->getPagesDir() == false) { $pagesDir = $app->getRootDir() . PieCrustDefaults::CONTENT_PAGES_DIR; $log->info("Creating pages directory: {$pagesDir}"); mkdir($pagesDir, 0777, true); $app->setPagesDir($pagesDir); } // Create the path of the feed. $slug = $result->command->command->args['url']; $slug = ltrim($slug, '/\\'); $fullPath = $app->getPagesDir() . $slug; if (!preg_match('/\\.[a-z0-9]+$/i', $slug)) { $fullPath .= '.html'; } $relativePath = PieCrustHelper::getRelativePath($app, $fullPath); if (file_exists($fullPath)) { throw new PieCrustException("Page already exists: {$relativePath}"); } $log->info("Creating feed: {$relativePath}"); // Get the feed template. $templatePath = PieCrustDefaults::RES_DIR() . 'prepare/rss.html'; if ($result->command->command->options['use_atom']) { $templatePath = PieCrustDefaults::RES_DIR() . 'prepare/atom.html'; } $template = file_get_contents($templatePath); // Write the contents. if (!is_dir(dirname($fullPath))) { mkdir(dirname($fullPath), 0777, true); } $f = fopen($fullPath, 'w'); fwrite($f, $template); fclose($f); $fullUrl = $app->getConfig()->getValue('site/root') . $slug; $log->info("Don't forget to add a link into your main page's header like so:"); $log->info("<link rel=\"alternate\" type=\"application/rss+xml\" href=\"{$fullUrl}\" />"); }
public function run(ChefContext $context) { $result = $context->getResult(); $app = $context->getApp(); $log = $context->getLog(); // Create the pages directory if it doesn't exist. if ($app->getPagesDir() == false) { $pagesDir = $app->getRootDir() . PieCrustDefaults::CONTENT_PAGES_DIR; $log->info("Creating pages directory: {$pagesDir}"); mkdir($pagesDir, 0777, true); $app->setPagesDir($pagesDir); } // Create the path of the new page. $slug = $result->command->command->args['slug']; $slug = ltrim($slug, '/\\'); $fullPath = $app->getPagesDir() . $slug; if (!preg_match('/\\.[a-z0-9]+$/i', $slug)) { $fullPath .= '.html'; } $relativePath = PieCrustHelper::getRelativePath($app, $fullPath); if (file_exists($fullPath)) { throw new PieCrustException("Page already exists: {$relativePath}"); } $log->info("Creating new page: {$relativePath}"); // Create the title and date/time of post. $title = preg_replace('/[\\-_]+/', ' ', $slug); $title = ucwords($title); $date = date('Y-m-d H:i'); // Write the contents. if (!is_dir(dirname($fullPath))) { mkdir(dirname($fullPath), 0777, true); } $f = fopen($fullPath, 'w'); fwrite($f, "---\n"); fwrite($f, "title: {$title}\n"); fwrite($f, "date: {$date}\n"); fwrite($f, "---\n"); fwrite($f, "A new page.\n"); fclose($f); }
/** * Gets the page's data for page rendering. * * It's better to call IPage::getData, which calls this function, because it * will also cache the results. It's useful for example when pagination * results needs to be re-used. */ public static function getPageData(IPage $page) { $pieCrust = $page->getApp(); $paginator = new Paginator($page); $assetor = new Assetor($page); $linker = new Linker($page); if ($page->getPaginationDataSource() != null) { $paginator->setPaginationDataSource($page->getPaginationDataSource()); } $data = array('page' => $page->getConfig()->get(), 'asset' => $assetor, 'pagination' => $paginator, 'link' => $linker); $data['page']['url'] = PieCrustHelper::formatUri($pieCrust, $page->getUri()); $data['page']['slug'] = $page->getUri(); $data['page']['timestamp'] = $page->getDate(); $dateFormat = PageHelper::getConfigValueUnchecked($page, 'date_format', $page->getConfig()->getValueUnchecked('blog')); $data['page']['date'] = date($dateFormat, $page->getDate()); switch ($page->getPageType()) { case IPage::TYPE_TAG: if (is_array($page->getPageKey())) { $data['tag'] = implode(' + ', $page->getPageKey()); } else { $data['tag'] = $page->getPageKey(); } break; case IPage::TYPE_CATEGORY: $data['category'] = $page->getPageKey(); break; } $extraData = $page->getExtraPageData(); if ($extraData) { if (is_array($extraData)) { $data = Configuration::mergeArrays($data, $extraData); } else { $data['extra'] = $extraData; } } return $data; }
/** * Ensures the configuration has been loaded. */ protected function ensureConfig() { if ($this->config == null) { $configCache = $this->cachingEnabled ? $this->getCacheDir() : false; $configPaths = array(); $themeDir = $this->getThemeDir(); if ($themeDir !== false) { $configPaths[] = $themeDir . PieCrustDefaults::THEME_CONFIG_PATH; } $configPaths[] = $this->rootDir . PieCrustDefaults::CONFIG_PATH; $this->config = new PieCrustConfiguration($configPaths, $configCache); if ($themeDir !== false) { // We'll need to patch the templates directories to be relative // to the site's root, as opposed to the theme root. $relativeThemeDir = PieCrustHelper::getRelativePath($this, $themeDir); $this->config->setFixup(function ($i, &$c) use($relativeThemeDir) { if ($i == 0) { if (!isset($c['site'])) { return; } if (!isset($c['site']['templates_dirs'])) { return; } if (!is_array($c['site']['templates_dirs'])) { $c['site']['templates_dirs'] = array($c['site']['templates_dirs']); } foreach ($c['site']['templates_dirs'] as &$dir) { $dir = $relativeThemeDir . $dir; } } }); } } }
public function transformGeneric($value, $formatterName = null) { return PieCrustHelper::formatText($this->pieCrust, $value, $formatterName); }
protected static function buildUrlBase(IPage $page, $assetUrlBaseRemap) { $siteRoot = $page->getApp()->getConfig()->getValueUnchecked('site/root'); $relativePath = str_replace('\\', '/', PieCrustHelper::getRelativePath($page->getApp(), $page->getPath(), true)); $uri = $page->getUri(); $prettyUrls = PageHelper::getConfigValue($page, 'pretty_urls', 'site'); if (!$prettyUrls) { // Remove the extension from the URI (if any), because without 'pretty URLs', // we want to copy assets to a directory named after the page's filename // (without the extension). See `PageBaker` for more information. $uriInfo = pathinfo($uri); $uri = $uriInfo['dirname']; if ($uri == '.') { $uri = ''; } else { $uri .= '/'; } $uri .= $uriInfo['filename']; } $replacements = array('%site_root%' => $siteRoot, '%path%' => $relativePath, '%uri%' => $uri); return str_replace(array_keys($replacements), array_values($replacements), $assetUrlBaseRemap); }
private function findTemplates($context, $templateDir) { $logger = $context->getLog(); $pieCrust = $context->getApp(); $result = $context->getResult(); $rootDir = $pieCrust->getRootDir(); $rootDir = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $rootDir); $exact = $result->command->options['exact']; $pattern = $result->command->args['pattern']; $fullPath = $result->command->options['full_path']; $returnComponents = $result->command->options['page_components']; $foundAny = false; $dirIt = new \RecursiveDirectoryIterator($templateDir); $it = new \RecursiveIteratorIterator($dirIt); foreach ($it as $path) { if ($it->isDot()) { continue; } $relativePath = PieCrustHelper::getRelativePath($pieCrust, $path->getPathname()); if ($exact) { // Match the path exactly, or pass. if (str_replace('\\', '/', $pattern) != str_replace('\\', '/', $path->getPathname())) { continue; } } else { if ($pattern) { // Match the regex, or pass. if (!preg_match($pattern, $relativePath)) { continue; } } } // Get the path to print. $finalPath = $relativePath; if ($fullPath) { $finalPath = $path->getPathname(); } $finalPath = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $finalPath); // Print the information! if ($returnComponents) { $logger->info("path: {$finalPath}"); $logger->info("type: template"); $foundAny = true; } else { $logger->info($finalPath); $foundAny = true; } } return $foundAny; }
protected function convertPage($relative, $outputPath, $isTemplate = false) { $this->logger->debug("Converting {$relative}"); $pieCrustRelative = PieCrustHelper::getRelativePath($this->pieCrust, $outputPath); $this->logger->debug(" -> {$pieCrustRelative}"); $this->modified[$pieCrustRelative] = array(); $absolute = $this->rootDir . $relative; $contents = file_get_contents($absolute); $wrapContentTag = true; $header = Configuration::parseHeader($contents); $text = substr($contents, $header->textOffset); $textBeforeConversion = $text; if ($isTemplate) { $config = $header->config; if (isset($config['layout'])) { // Liquid doesn't support template inheritance, // but Twig does. $text = "{% extends '{$config['layout']}.html' %}\n\n" . "{% block jekyllcontent %}\n" . $text . "\n" . "{% endblock %}\n"; $wrapContentTag = false; $this->modified[$pieCrustRelative]['layout_extends'] = true; } } else { // Convert the config. $config = $header->config; if (isset($config['layout'])) { // PieCrust uses 'none' instead of 'nil'. if ($config['layout'] == 'nil') { $config['layout'] = 'none'; } } // PieCrust defines everything in the config header, // including the format of the text. $pathinfo = pathinfo($relative); if ($pathinfo['extension'] != 'html') { $config['format'] = $pathinfo['extension']; } else { $config['format'] = 'none'; } } // Convert the template stuff we can: // - content tag may have to be wrapped in a `jekyllcontent` // because Jekyll uses implicit layout inheritance // placements. if ($wrapContentTag) { $text = preg_replace('/{{\\s*content\\s*}}/', '{% block jekyllcontent %}{{ content }}{% endblock %}', $text); } // - list of posts $text = preg_replace('/(?<=\\{%|{)([^\\}]*)site.posts/', '\\1blog.posts', $text); $text = preg_replace('/(?<=\\{%|{)([^\\}]*)paginator.posts/', '\\1pagination.posts', $text); // - list of categories or tags $text = preg_replace('/(?<=\\{%|{)([^\\}]*)site.categories/', '\\1blog.categories', $text); $text = preg_replace('/(?<=\\{%|{)([^\\}]*)site.tags/', '\\1blog.tags', $text); // - list of related posts $text = preg_replace('/(?<=\\{%|{)(?<!%\\})site.related_posts/', '\\1pagination.related_posts', $text); // - enumeration limits $text = preg_replace('/{%\\s*for\\s+([^}]+)\\s+limit\\:\\s*(\\d+)/', '{% for \\1 | slice(0, \\2)', $text); $text = preg_replace('/{%\\s*for\\s+([^}]+)\\s+offset\\:\\s*(\\d+)/', '{% for \\1 | slice(\\2)', $text); // - code highlighting $text = preg_replace('/{%\\s*highlight\\s+([\\w\\d]+)\\s*%}/', '{% geshi \'\\1\' %}', $text); $text = preg_replace('/{%\\s*endhighlight\\s*%}/', '{% endgeshi %}', $text); // - unless tag $text = preg_replace('/{%\\s*unless\\s+([^}]+)\\s*%}/', '{% if not \\1 %}', $text); $text = preg_replace('/{%\\s*endunless\\s*%}/', '{% endif %}', $text); // - variable assignment $text = preg_replace('/\\{%\\s*assign\\s+/', '{% set ', $text); // - include tag $text = preg_replace('/\\{%\\s*include\\s+([\\w\\d\\.\\-_]+)\\s*%}/', '{% include "\\1" %}', $text); // - truncate filter $text = preg_replace('/\\|\\s*truncate\\:\\s*(\\d+)/', '|slice(0, \\1)', $text); // - date filter $text = preg_replace('/\\|\\s*date\\:\\s*"([^"]+)"/', '|date("\\1")', $text); // - some filters we don't need $text = preg_replace('/\\|\\s*date_to_string/', '', $text); // Create the destination directory if needed. if (!is_dir(dirname($outputPath))) { mkdir(dirname($outputPath), 0755, true); } // Create a backup file if we converted a lot of stuff. if ($text != $textBeforeConversion) { $this->modified[$pieCrustRelative]['liquid_to_twig'] = true; // Add a backup of the original content. $backupPath = $outputPath . '.original'; file_put_contents($backupPath, $contents); } // Save the converted contents. $convertedContents = ''; if (!$isTemplate and count($config) > 0) { $convertedContents .= "---\n"; $convertedContents .= Yaml::dump($config, 3); $convertedContents .= "---\n"; } $convertedContents .= $text; file_put_contents($outputPath, $convertedContents); }
/** * Creates a new Page instance given a path. */ public static function createFromPath(IPieCrust $pieCrust, $path, $pageType = IPage::TYPE_REGULAR, $pageNumber = 1, $blogKey = null, $pageKey = null, $date = null) { if ($path == null) { throw new InvalidArgumentException("The given path is null."); } if (!is_file($path)) { throw new InvalidArgumentException("The given path does not exist: " . $path); } $relativePath = PieCrustHelper::getRelativePath($pieCrust, $path, true); $uri = UriBuilder::buildUri($relativePath); return new Page($pieCrust, $uri, $path, $pageType, $blogKey, $pageKey, $pageNumber, $date); }
protected function getThemeMetadata(IPieCrust $app, $sources, $pattern, $exact, $log) { $metadata = array(); foreach ($sources as $source) { $repository = PieCrustHelper::getRepository($app, $source); $repositoryClass = get_class($repository); if ($log) { $log->debug("Loading themes metadata from: " . $source); } $themes = $repository->getThemes($source); foreach ($themes as $theme) { // Make sure we have the required properties. if (!isset($theme['name'])) { $theme['name'] = 'UNNAMED THEME'; } if (!isset($theme['description'])) { $theme['description'] = 'NO DESCRIPTION AVAILABLE.'; } $theme['repository_class'] = $repositoryClass; // Find if the theme matches the query. $matches = true; if ($exact) { $matches = strcasecmp($theme['name'], $pattern) == 0; } elseif ($pattern) { $matchesName = stristr($theme['name'], $pattern) != false; $matchesDescription = stristr($theme['description'], $pattern) != false; $matches = ($matchesName or $matchesDescription); } if ($matches) { // Get the theme, and exit if we only want one. $metadata[] = $theme; if ($exact) { break; } } } } return $metadata; }
/** * Gets the page's data for page rendering. * * It's better to call IPage::getData, which calls this function, because it * will also cache the results. It's useful for example when pagination * results needs to be re-used. */ public static function getPageData(IPage $page) { $pieCrust = $page->getApp(); $paginator = new Paginator($page); $assetor = new Assetor($page); $linker = new Linker($page); $recursiveLinker = new RecursiveLinkerIterator($linker); if ($page->getPaginationDataSource() != null) { $paginator->setPaginationDataSource($page->getPaginationDataSource()); } $data = array('page' => $page->getConfig()->get(), 'assets' => $assetor, 'pagination' => $paginator, 'siblings' => $linker, 'family' => $recursiveLinker); $data['page']['url'] = PieCrustHelper::formatUri($pieCrust, $page->getUri()); $data['page']['slug'] = $page->getUri(); $data['page']['timestamp'] = $page->getDate(true); $dateFormat = PageHelper::getConfigValueUnchecked($page, 'date_format', $page->getConfig()->getValueUnchecked('blog')); $data['page']['date'] = date($dateFormat, $page->getDate(true)); switch ($page->getPageType()) { case IPage::TYPE_TAG: if (is_array($page->getPageKey())) { $data['tag'] = implode(' + ', $page->getPageKey()); } else { $data['tag'] = $page->getPageKey(); } if (strpos($data['tag'], '-') >= 0) { // The tag may have been slugified. Let's cheat a bit by looking at // the first tag that matches in the first pagination post, and // using that instead. $paginationPosts = $paginator->posts(); if (count($paginationPosts) > 0) { $firstPost = $paginationPosts[0]; $firstPostTags = $firstPost['tags']; if (!is_array($firstPostTags)) { $firstPostTags = array($firstPostTags); } $flags = $pieCrust->getConfig()->getValue('site/slugify_flags'); if (is_array($page->getPageKey())) { $pageKey = $page->getPageKey(); foreach ($firstPostTags as $t) { $st = UriBuilder::slugify($t, $flags); foreach ($pageKey as &$pk) { if ($st == $pk) { $pk = $t; break; } } } if ($page->getPageKey() == null) { $page->setPageKey($pageKey); } $data['tag'] = implode(' + ', $pageKey); } else { foreach ($firstPostTags as $t) { if (UriBuilder::slugify($t, $flags) == $data['tag']) { if ($page->getPageKey() == null) { $page->setPageKey($t); } $data['tag'] = $t; break; } } } } } break; case IPage::TYPE_CATEGORY: $data['category'] = $page->getPageKey(); if (strpos($page->getPageKey(), '-') >= 0) { // Same remark as for tags. $paginationPosts = $paginator->posts(); if (count($paginationPosts) > 0) { $firstPost = $paginationPosts[0]; if ($page->getPageKey() == null) { $page->setPageKey($firstPost['category']); } $data['category'] = $firstPost['category']; } } break; } $extraData = $page->getExtraPageData(); if ($extraData) { if (is_array($extraData)) { $data = Configuration::mergeArrays($data, $extraData); } else { $data['extra'] = $extraData; } } return $data; }
protected function formatContentsUnsafe(array $rawSegments) { $data = DataBuilder::getPageRenderingData($this->page); $pieCrust = $this->page->getApp(); $templateEngineName = $this->page->getConfig()->getValue('template_engine'); $templateEngine = PieCrustHelper::getTemplateEngine($pieCrust, $templateEngineName); if (!$templateEngine) { throw new PieCrustException("Unknown template engine '{$templateEngineName}'."); } $contents = array(); foreach ($rawSegments as $key => $pieces) { $contents[$key] = ''; foreach ($pieces as $piece) { $content = $piece['content']; $format = $piece['format']; ob_start(); try { $templateEngine->renderString($content, $data); $renderedContent = ob_get_clean(); } catch (Exception $e) { ob_end_clean(); throw $e; } if (!$format) { $format = $this->page->getConfig()->getValue('format'); } $renderedAndFormattedContent = PieCrustHelper::formatText($pieCrust, $renderedContent, $format); $contents[$key] .= $renderedAndFormattedContent; } } if (!empty($contents['content'])) { $matches = array(); if (preg_match('/^<!--\\s*(more|(page)?break)\\s*-->\\s*$/m', $contents['content'], $matches, PREG_OFFSET_CAPTURE)) { // Add a special content segment for the "intro/abstract" part // of the article. $offset = $matches[0][1]; $abstract = substr($contents['content'], 0, $offset); $this->page->getConfig()->appendValue('segments', 'content.abstract'); $contents['content.abstract'] = $abstract; } } return $contents; }
public function run(ChefContext $context) { $logger = $context->getLog(); $pieCrust = $context->getApp(); $result = $context->getResult(); // Get some options. $exact = $result->command->options['exact']; $fullPath = $result->command->options['full_path']; // If no type filters are given, return all types. $returnAllTypes = ($result->command->options['pages'] == false and $result->command->options['posts'] == false and $result->command->options['templates'] == false); // Validate the argument. $pattern = $result->command->args['pattern']; if ($exact) { // Check we have a path to match, and get its absolute value. if (!$pattern) { throw new PieCrustException("You need to specify a path when using the `--exact` option."); } $pattern = PathHelper::getAbsolutePath($pattern); } else { // If a pattern was given, get the Regex'd version. if ($pattern) { $pattern = PathHelper::globToRegex($pattern); } } // Get the pages and posts. $pages = array(); if ($returnAllTypes or $result->command->options['pages']) { $pages = PageHelper::getPages($pieCrust); } if ($returnAllTypes or $result->command->options['posts']) { $blogKeys = $pieCrust->getConfig()->getValue('site/blogs'); if ($result->command->options['blog']) { $blogKeys = array($result->command->options['blog']); } foreach ($blogKeys as $blogKey) { $pages = array_merge($pages, PageHelper::getPosts($pieCrust, $blogKey)); } } // Get some other stuff. $returnComponents = $result->command->options['page_components']; // Get a regex for the posts file-naming convention. $fs = FileSystem::create($pieCrust); $pathComponentsRegex = preg_quote($fs->getPostPathFormat(), '/'); $pathComponentsRegex = str_replace(array('%year%', '%month%', '%day%', '%slug%'), array('(\\d{4})', '(\\d{2})', '(\\d{2})', '(.+)'), $pathComponentsRegex); $pathComponentsRegex = '/' . $pathComponentsRegex . '/'; // Print the matching pages. foreach ($pages as $page) { if ($result->command->options['no_special']) { // Skip special pages. if ($page->getUri() == PieCrustDefaults::CATEGORY_PAGE_NAME or $page->getUri() == PieCrustDefaults::TAG_PAGE_NAME) { continue; } } if ($exact) { // Match the path exactly, or pass. if (str_replace('\\', '/', $pattern) != str_replace('\\', '/', $page->getPath())) { continue; } } else { if ($pattern) { // Match the regex, or pass. if (!preg_match($pattern, $page->getUri())) { continue; } } } $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $page->getPath()); if (!$fullPath) { $path = PieCrustHelper::getRelativePath($pieCrust, $path); } if ($returnComponents) { $components = array('path' => $path, 'type' => 'page', 'uri' => $page->getUri(), 'slug' => $page->getUri()); if (PageHelper::isPost($page)) { $matches = array(); if (preg_match($pathComponentsRegex, str_replace('\\', '/', $path), $matches) !== 1) { throw new PieCrustException("Can't extract path components from path: {$path}"); } $components['type'] = 'post'; $components['year'] = $matches[1]; $components['month'] = $matches[2]; $components['day'] = $matches[3]; $components['slug'] = $matches[4]; } $str = ''; foreach ($components as $k => $v) { $str .= $k . ': ' . $v . PHP_EOL; } $logger->info($str); } else { $logger->info($path); } } // Get the template files and print them. if ($returnAllTypes or $result->command->options['templates']) { $templatesDirs = $pieCrust->getTemplatesDirs(); foreach ($templatesDirs as $dir) { $dirIt = new \RecursiveDirectoryIterator($dir); $it = new \RecursiveIteratorIterator($dirIt); foreach ($it as $path) { if ($it->isDot()) { continue; } $relativePath = PieCrustHelper::getRelativePath($pieCrust, $path->getPathname()); if ($exact) { // Match the path exactly, or pass. if (str_replace('\\', '/', $pattern) != str_replace('\\', '/', $path->getPathname())) { continue; } } else { if ($pattern) { // Match the regex, or pass. if (!preg_match($pattern, $relativePath)) { continue; } } } // Get the path to print. $finalPath = $relativePath; if ($fullPath) { $finalPath = $path->getPathname(); } $finalPath = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $finalPath); // Print the information! if ($returnComponents) { $logger->info("path: {$finalPath}"); $logger->info("type: template"); } else { $logger->info($finalPath); } } } } return 0; }
public function getSubPageUri($index) { $uri = $this->page->getUri(); if ($index > 1) { if ($uri != '') { $uri .= '/'; } $uri .= $index; } return PieCrustHelper::formatUri($this->page->getApp(), $uri); }
protected function getPluginMetadata(IPieCrust $app, $sources, $pattern, $exact, $log) { $metadata = array(); foreach ($sources as $source) { $repository = PieCrustHelper::getRepository($app, $source); $repositoryClass = get_class($repository); if ($log) { $log->debug("Loading plugins metadata from: " . $source); } $plugins = $repository->getPlugins($source); foreach ($plugins as $plugin) { // Make sure we have the required properties. if (!isset($plugin['name'])) { $plugin['name'] = 'UNNAMED PLUGIN'; } if (!isset($plugin['description'])) { $plugin['description'] = 'NO DESCRIPTION AVAILABLE.'; } $plugin['repository_class'] = $repositoryClass; // Find if the plugin matches the query. $matches = true; if ($exact) { $matches = strcasecmp($plugin['name'], $pattern) == 0; } elseif ($pattern) { $matchesName = stristr($plugin['name'], $pattern) != false; $matchesDescription = stristr($plugin['description'], $pattern) != false; $matches = ($matchesName or $matchesDescription); } if ($matches) { $metadata[] = $plugin; } } } return $metadata; }
private function getSafeBlogKey($blogKey) { if ($blogKey == null) { return PieCrustHelper::getDefaultBlogKey($this->pieCrust); } else { $blogKeys = $this->pieCrust->getConfig()->getValueUnchecked('site/blogs'); if (!in_array($blogKey, $blogKeys)) { throw new PieCrustException("No such blog in the website: {$blogKey}"); } return $blogKey; } }