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