/**
  * The process() method handles the "meat" of the template processing.
  *
  * It takes care of caching the output (via {@link Cache}), as well as
  * replacing the special "$Content" and "$Layout" placeholders with their
  * respective subtemplates.
  *
  * The method injects extra HTML in the header via {@link Requirements::includeInHTML()}.
  *
  * Note: You can call this method indirectly by {@link ViewableData->renderWith()}.
  *
  * @param ViewableData $item
  * @param array|null $arguments Arguments to an included template
  * @param ViewableData $inheritedScope The current scope of a parent template including a sub-template
  * @return DBHTMLText Parsed template output.
  */
 public function process($item, $arguments = null, $inheritedScope = null)
 {
     SSViewer::$topLevel[] = $item;
     $template = $this->chosen;
     $cacheFile = TEMP_FOLDER . "/.cache" . str_replace(array('\\', '/', ':'), '.', Director::makeRelative(realpath($template)));
     $lastEdited = filemtime($template);
     if (!file_exists($cacheFile) || filemtime($cacheFile) < $lastEdited) {
         $content = file_get_contents($template);
         $content = $this->parseTemplateContent($content, $template);
         $fh = fopen($cacheFile, 'w');
         fwrite($fh, $content);
         fclose($fh);
     }
     $underlay = array('I18NNamespace' => basename($template));
     // Makes the rendered sub-templates available on the parent item,
     // through $Content and $Layout placeholders.
     foreach (array('Content', 'Layout') as $subtemplate) {
         $sub = null;
         if (isset($this->subTemplates[$subtemplate])) {
             $sub = $this->subTemplates[$subtemplate];
         } elseif (!is_array($this->templates)) {
             $sub = ['type' => $subtemplate, $this->templates];
         } elseif (!array_key_exists('type', $this->templates) || !$this->templates['type']) {
             $sub = array_merge($this->templates, ['type' => $subtemplate]);
         }
         if ($sub) {
             $subtemplateViewer = clone $this;
             // Disable requirements - this will be handled by the parent template
             $subtemplateViewer->includeRequirements(false);
             // Select the right template
             $subtemplateViewer->setTemplate($sub);
             if ($subtemplateViewer->exists()) {
                 $underlay[$subtemplate] = $subtemplateViewer->process($item, $arguments);
             }
         }
     }
     $output = $this->includeGeneratedTemplate($cacheFile, $item, $arguments, $underlay, $inheritedScope);
     if ($this->includeRequirements) {
         $output = Requirements::includeInHTML($output);
     }
     array_pop(SSViewer::$topLevel);
     // If we have our crazy base tag, then fix # links referencing the current page.
     $rewrite = SSViewer::config()->get('rewrite_hash_links');
     if ($this->rewriteHashlinks && $rewrite) {
         if (strpos($output, '<base') !== false) {
             if ($rewrite === 'php') {
                 $thisURLRelativeToBase = "<?php echo \\SilverStripe\\Core\\Convert::raw2att(preg_replace(\"/^(\\\\/)+/\", \"/\", \$_SERVER['REQUEST_URI'])); ?>";
             } else {
                 $thisURLRelativeToBase = Convert::raw2att(preg_replace("/^(\\/)+/", "/", $_SERVER['REQUEST_URI']));
             }
             $output = preg_replace('/(<a[^>]+href *= *)"#/i', '\\1"' . $thisURLRelativeToBase . '#', $output);
         }
     }
     return DBField::create_field('HTMLFragment', $output);
 }