Example #1
0
 /**
  * Takes an individual page and processes the taxonomies configured in its header. It
  * then adds those taxonomies to the map
  *
  * @param Page $page the page to process
  * @param array $page_taxonomy
  */
 public function addTaxonomy(Page $page, $page_taxonomy = null)
 {
     if (!$page_taxonomy) {
         $page_taxonomy = $page->taxonomy();
     }
     /** @var Config $config */
     $config = $this->grav['config'];
     if ($config->get('site.taxonomies') && count($page_taxonomy) > 0) {
         foreach ((array) $config->get('site.taxonomies') as $taxonomy) {
             if (isset($page_taxonomy[$taxonomy])) {
                 foreach ((array) $page_taxonomy[$taxonomy] as $item) {
                     // TODO: move to pages class?
                     $this->taxonomy_map[$taxonomy][(string) $item][$page->path()] = array('slug' => $page->slug());
                 }
             }
         }
     }
 }
Example #2
0
 /**
  * Takes an individual page and processes the taxonomies configured in its header. It
  * then adds those taxonomies to the map
  *
  * @param Page  $page the page to process
  * @param array $page_taxonomy
  */
 public function addTaxonomy(Page $page, $page_taxonomy = null)
 {
     if (!$page_taxonomy) {
         $page_taxonomy = $page->taxonomy();
     }
     if (!$page->published() || empty($page_taxonomy)) {
         return;
     }
     /** @var Config $config */
     $config = $this->grav['config'];
     if ($config->get('site.taxonomies')) {
         foreach ((array) $config->get('site.taxonomies') as $taxonomy) {
             if (isset($page_taxonomy[$taxonomy])) {
                 foreach ((array) $page_taxonomy[$taxonomy] as $item) {
                     $this->taxonomy_map[$taxonomy][(string) $item][$page->path()] = ['slug' => $page->slug()];
                 }
             }
         }
     }
 }
Example #3
0
 /**
  * Gets and Sets the parent object for this page
  *
  * @param  Page $var the parent page object
  * @return Page|null the parent page object if it exists.
  */
 public function parent(Page $var = null)
 {
     if ($var) {
         $this->parent = $var->path();
         return $var;
     }
     /** @var Pages $pages */
     $pages = self::getGrav()['pages'];
     return $pages->get($this->parent);
 }
Example #4
0
 /**
  * Recursive function to load & build page relationships.
  *
  * @param string $directory
  * @param Page|null $parent
  * @return Page
  * @throws \RuntimeException
  * @internal
  */
 protected function recurse($directory, Page &$parent = null)
 {
     $directory = rtrim($directory, DS);
     $iterator = new \DirectoryIterator($directory);
     $page = new Page();
     /** @var Config $config */
     $config = $this->grav['config'];
     $page->path($directory);
     if ($parent) {
         $page->parent($parent);
     }
     $page->orderDir($config->get('system.pages.order.dir'));
     $page->orderBy($config->get('system.pages.order.by'));
     // Add into instances
     if (!isset($this->instances[$page->path()])) {
         $this->instances[$page->path()] = $page;
         if ($parent && $page->path()) {
             $this->children[$parent->path()][$page->path()] = array('slug' => $page->slug());
         }
     } else {
         throw new \RuntimeException('Fatal error when creating page instances.');
     }
     // set current modified of page
     $last_modified = $page->modified();
     // flat for content availability
     $content_exists = false;
     /** @var \DirectoryIterator $file */
     foreach ($iterator as $file) {
         if ($file->isDot()) {
             continue;
         }
         $name = $file->getFilename();
         if ($file->isFile()) {
             // Update the last modified if it's newer than already found
             if ($file->getBasename() !== '.DS_Store' && ($modified = $file->getMTime()) > $last_modified) {
                 $last_modified = $modified;
             }
             if (preg_match('/^[^.].*' . CONTENT_EXT . '$/', $name)) {
                 $page->init($file);
                 $content_exists = true;
                 if ($config->get('system.pages.events.page')) {
                     $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page]));
                 }
             }
         } elseif ($file->isDir()) {
             if (!$page->path()) {
                 $page->path($file->getPath());
             }
             $path = $directory . DS . $name;
             $child = $this->recurse($path, $page);
             if (Utils::startsWith($name, '_')) {
                 $child->routable(false);
             }
             $this->children[$page->path()][$child->path()] = array('slug' => $child->slug());
             if ($config->get('system.pages.events.page')) {
                 $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
             }
         }
     }
     // Set routability to false if no page found
     if (!$content_exists) {
         $page->routable(false);
     }
     // Override the modified and ID so that it takes the latest change into account
     $page->modified($last_modified);
     $page->id($last_modified . md5($page->filePath()));
     // Sort based on Defaults or Page Overridden sort order
     $this->children[$page->path()] = $this->sort($page);
     return $page;
 }
Example #5
0
 /**
  * Recursive function to load & build page relationships.
  *
  * @param string $directory
  * @param Page|null $parent
  * @return Page
  * @throws \RuntimeException
  * @internal
  */
 protected function recurse($directory, Page &$parent = null)
 {
     $directory = rtrim($directory, DS);
     $page = new Page();
     /** @var Config $config */
     $config = $this->grav['config'];
     /** @var Language $language */
     $language = $this->grav['language'];
     // stuff to do at root page
     if ($parent === null) {
         // Fire event for memory and time consuming plugins...
         if ($config->get('system.pages.events.page')) {
             $this->grav->fireEvent('onBuildPagesInitialized');
         }
     }
     $page->path($directory);
     if ($parent) {
         $page->parent($parent);
     }
     $page->orderDir($config->get('system.pages.order.dir'));
     $page->orderBy($config->get('system.pages.order.by'));
     // Add into instances
     if (!isset($this->instances[$page->path()])) {
         $this->instances[$page->path()] = $page;
         if ($parent && $page->path()) {
             $this->children[$parent->path()][$page->path()] = array('slug' => $page->slug());
         }
     } else {
         throw new \RuntimeException('Fatal error when creating page instances.');
     }
     $content_exists = false;
     $pages_found = glob($directory . '/*' . CONTENT_EXT);
     $page_extensions = $language->getFallbackPageExtensions();
     if ($pages_found) {
         foreach ($page_extensions as $extension) {
             foreach ($pages_found as $found) {
                 if (preg_match('/^.*\\/[0-9A-Za-z\\-\\_]+(' . $extension . ')$/', $found)) {
                     $page_found = $found;
                     $page_extension = $extension;
                     break 2;
                 }
             }
         }
     }
     if ($parent && !empty($page_found)) {
         $file = new \SplFileInfo($page_found);
         $page->init($file, $page_extension);
         $content_exists = true;
         if ($config->get('system.pages.events.page')) {
             $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page]));
         }
     }
     // set current modified of page
     $last_modified = $page->modified();
     /** @var \DirectoryIterator $file */
     foreach (new \FilesystemIterator($directory) as $file) {
         $name = $file->getFilename();
         // Ignore all hidden files if set.
         if ($this->ignore_hidden) {
             if ($name && $name[0] == '.') {
                 continue;
             }
         }
         if ($file->isFile()) {
             // Update the last modified if it's newer than already found
             if (!in_array($file->getBasename(), $this->ignore_files) && ($modified = $file->getMTime()) > $last_modified) {
                 $last_modified = $modified;
             }
         } elseif ($file->isDir() && !in_array($file->getFilename(), $this->ignore_folders)) {
             if (!$page->path()) {
                 $page->path($file->getPath());
             }
             $path = $directory . DS . $name;
             $child = $this->recurse($path, $page);
             if (Utils::startsWith($name, '_')) {
                 $child->routable(false);
             }
             $this->children[$page->path()][$child->path()] = array('slug' => $child->slug());
             if ($config->get('system.pages.events.page')) {
                 $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
             }
         }
     }
     // Set routability to false if no page found
     if (!$content_exists) {
         $page->routable(false);
     }
     // Override the modified and ID so that it takes the latest change into account
     $page->modified($last_modified);
     $page->id($last_modified . md5($page->filePath()));
     // Sort based on Defaults or Page Overridden sort order
     $this->children[$page->path()] = $this->sort($page);
     return $page;
 }
Example #6
0
 /**
  * Add a single page to a collection
  *
  * @param Page $page
  *
  * @return $this
  */
 public function addPage(Page $page)
 {
     $this->items[$page->path()] = ['slug' => $page->slug()];
     return $this;
 }
Example #7
0
 /**
  * Twig process that renders a page item. It supports two variations:
  * 1) Handles modular pages by rendering a specific page based on its modular twig template
  * 2) Renders individual page items for twig processing before the site rendering
  *
  * @param  Page   $item    The page item to render
  * @param  string $content Optional content override
  * @return string          The rendered output
  * @throws \Twig_Error_Loader
  */
 public function processPage(Page $item, $content = null)
 {
     $content = $content !== null ? $content : $item->content();
     // override the twig header vars for local resolution
     $this->grav->fireEvent('onTwigPageVariables');
     $twig_vars = $this->twig_vars;
     $twig_vars['page'] = $item;
     $twig_vars['media'] = $item->media();
     $twig_vars['header'] = $item->header();
     $local_twig = clone $this->twig;
     $modular_twig = $item->modularTwig();
     $process_twig = isset($item->header()->process['twig']) ? $item->header()->process['twig'] : false;
     try {
         // Process Modular Twig
         if ($modular_twig) {
             $twig_vars['content'] = $content;
             $template = $item->template() . TEMPLATE_EXT;
             $output = $content = $local_twig->render($template, $twig_vars);
         }
         // Process in-page Twig
         if (!$modular_twig || $modular_twig && $process_twig) {
             $name = '@Page:' . $item->path();
             $this->setTemplate($name, $content);
             $output = $local_twig->render($name, $twig_vars);
         }
     } catch (\Twig_Error_Loader $e) {
         throw new \RuntimeException($e->getRawMessage(), 404, $e);
     }
     return $output;
 }
Example #8
0
 /**
  * Converts links from absolute '/' or relative (../..) to a grav friendly format
  *
  * @param         $page         the current page to use as reference
  * @param  string $markdown_url the URL as it was written in the markdown
  *
  * @return string the more friendly formatted url
  */
 public static function convertUrl(Page $page, $markdown_url)
 {
     $grav = Grav::instance();
     $pages_dir = $grav['locator']->findResource('page://');
     $base_url = rtrim($grav['base_url'] . $grav['pages']->base(), '/');
     // if absolute and starts with a base_url move on
     if (pathinfo($markdown_url, PATHINFO_DIRNAME) == '.' && $page->url() == '/') {
         return '/' . $markdown_url;
         // no path to convert
     } elseif ($base_url != '' && Utils::startsWith($markdown_url, $base_url)) {
         return $markdown_url;
         // if contains only a fragment
     } elseif (Utils::startsWith($markdown_url, '#')) {
         return $markdown_url;
     } else {
         $target = null;
         // see if page is relative to this or absolute
         if (Utils::startsWith($markdown_url, '/')) {
             $normalized_url = Utils::normalizePath($base_url . $markdown_url);
             $normalized_path = Utils::normalizePath($pages_dir . $markdown_url);
         } else {
             $normalized_url = $base_url . Utils::normalizePath($page->route() . '/' . $markdown_url);
             $normalized_path = Utils::normalizePath($page->path() . '/' . $markdown_url);
         }
         // special check to see if path checking is required.
         $just_path = str_replace($normalized_url, '', $normalized_path);
         if ($just_path == $page->path()) {
             return $normalized_url;
         }
         $url_bits = parse_url($normalized_path);
         $full_path = $url_bits['path'];
         if (file_exists($full_path)) {
             // do nothing
         } elseif (file_exists(urldecode($full_path))) {
             $full_path = urldecode($full_path);
         } else {
             return $normalized_url;
         }
         $path_info = pathinfo($full_path);
         $page_path = $path_info['dirname'];
         $filename = '';
         if ($markdown_url == '..') {
             $page_path = $full_path;
         } else {
             // save the filename if a file is part of the path
             if (is_file($full_path)) {
                 if ($path_info['extension'] != 'md') {
                     $filename = '/' . $path_info['basename'];
                 }
             } else {
                 $page_path = $full_path;
             }
         }
         // get page instances and try to find one that fits
         $instances = $grav['pages']->instances();
         if (isset($instances[$page_path])) {
             $target = $instances[$page_path];
             $url_bits['path'] = $base_url . $target->route() . $filename;
             return Uri::buildUrl($url_bits);
         }
         return $normalized_url;
     }
 }
Example #9
0
 /**
  * Recursive function to load & build page relationships.
  *
  * @param string $directory
  * @param null $parent
  * @return Page
  * @throws \RuntimeException
  * @internal
  */
 protected function recurse($directory = PAGES_DIR, Page &$parent = null)
 {
     $directory = rtrim($directory, DS);
     $iterator = new \DirectoryIterator($directory);
     $page = new Page();
     $config = $this->grav['config'];
     $page->path($directory);
     if ($parent) {
         $page->parent($parent);
     }
     $page->orderDir($config->get('system.pages.order.dir'));
     $page->orderBy($config->get('system.pages.order.by'));
     // Add into instances
     if (!isset($this->instances[$page->path()])) {
         $this->instances[$page->path()] = $page;
         if ($parent && $page->path()) {
             $this->children[$parent->path()][$page->path()] = array('slug' => $page->slug());
         }
     } else {
         throw new \RuntimeException('Fatal error when creating page instances.');
     }
     $last_modified = 0;
     /** @var \DirectoryIterator $file */
     foreach ($iterator as $file) {
         $name = $file->getFilename();
         $date = $file->getMTime();
         if ($date > $last_modified) {
             $last_modified = $date;
         }
         if ($file->isFile() && Utils::endsWith($name, CONTENT_EXT)) {
             $page->init($file);
             if ($config->get('system.pages.events.page')) {
                 $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page]));
             }
         } elseif ($file->isDir() && !$file->isDot()) {
             if (!$page->path()) {
                 $page->path($file->getPath());
             }
             $path = $directory . DS . $name;
             $child = $this->recurse($path, $page);
             if (Utils::startsWith($name, '_')) {
                 $child->routable(false);
             }
             $this->children[$page->path()][$child->path()] = array('slug' => $child->slug());
             // set the modified time if not already set
             if (!$page->date()) {
                 $page->date($file->getMTime());
             }
             // set the last modified time on pages
             $this->lastModified($file->getMTime());
             if ($config->get('system.pages.events.page')) {
                 $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
             }
         }
     }
     // Override the modified and ID so that it takes the latest change
     // into account
     $page->modified($last_modified);
     $page->id($last_modified . md5($page->filePath()));
     // Sort based on Defaults or Page Overridden sort order
     $this->children[$page->path()] = $this->sort($page);
     return $page;
 }
 /**
  * Checks if a page has already been compiled yet.
  *
  * @param  Page    $page The page to check
  * @return boolean       Returns true if page has already been
  *                       compiled yet, false otherwise
  */
 protected function compileOnce(Page $page)
 {
     static $processed = [];
     $id = md5($page->path());
     // Make sure that contents is only processed once
     if (!isset($processed[$id]) || $processed[$id] < $page->modified()) {
         $processed[$id] = $page->modified();
         return true;
     }
     return false;
 }
Example #11
0
 /**
  * Twig process that renders a page item. It supports two variations:
  * 1) Handles modular pages by rendering a specific page based on its modular twig template
  * 2) Renders individual page items for twig processing before the site rendering
  *
  * @param  Page   $item    The page item to render
  * @param  string $content Optional content override
  * @return string          The rendered output
  * @throws \Twig_Error_Loader
  */
 public function processPage(Page $item, $content = null)
 {
     $content = $content !== null ? $content : $item->content();
     // override the twig header vars for local resolution
     $this->grav->fireEvent('onTwigPageVariables');
     $twig_vars = $this->twig_vars;
     $twig_vars['page'] = $item;
     $twig_vars['media'] = $item->media();
     $twig_vars['header'] = $item->header();
     $local_twig = clone $this->twig;
     // Get Twig template layout
     if ($item->modularTwig()) {
         $twig_vars['content'] = $content;
         $template = $item->template() . TEMPLATE_EXT;
         $output = $local_twig->render($template, $twig_vars);
     } else {
         $name = '@Page:' . $item->path();
         $this->setTemplate($name, $content);
         $output = $local_twig->render($name, $twig_vars);
     }
     return $output;
 }