Esempio n. 1
0
 /**
  * @param $template_name
  * @param null|array $template_dirs
  * @return array
  */
 public function loadTemplate($template_name, $template_dirs = null)
 {
     $key = $template_name;
     if ($template_dirs) {
         // If template directories were specified, use a hash to differentiate
         $key = join('-', array($template_name, sha1(join('|', $template_dirs))));
     }
     if (!isset($this->template_cache[$key])) {
         list($template, $origin) = $this->findTemplate($template_name, $template_dirs);
         if (!py_hasattr($template, 'render')) {
             try {
                 $template = DjaLoader::getTemplateFromString($template, $origin, $template_name);
             } catch (TemplateDoesNotExist $e) {
                 /*
                  * If compiling the template we found raises TemplateDoesNotExist,
                  * back off to returning the source and display name for the template
                  * we were asked to load. This allows for correct identification (later)
                  * of the actual template that does not exist.
                  */
                 return array($template, $origin);
             }
         }
         $this->template_cache[$key] = $template;
     }
     return array($this->template_cache[$key], null);
 }
Esempio n. 2
0
 /**
  * @param Context $context
  *
  * @return Template
  * @throws TemplateSyntaxError
  */
 public function getParent($context)
 {
     if ($this->parent_name_expr) {
         $parent = $this->parent_name_expr->resolve($context);
     } else {
         $parent = $this->parent_name;
     }
     if (!$parent) {
         $error_msg = 'Invalid template name in \'extends\' tag: ' . $parent . '.';
         if ($this->parent_name_expr) {
             $error_msg .= ' Got this from the \'' . $this->parent_name_expr->token . '\' variable.';
         }
         throw new TemplateSyntaxError($error_msg);
     }
     if (py_hasattr($parent, 'render')) {
         return $parent;
         // parent is a Template object
     }
     return DjaLoader::getTemplate($parent);
 }
Esempio n. 3
0
 /**
  * @param Context $context
  * @return SafeString|string
  * @throws Exception|TypeError|VariableDoesNotExist
  * @throws RuntimeError
  */
 public function render($context)
 {
     if (isset($context['forloop'])) {
         $parentloop = $context['forloop'];
     } else {
         $parentloop = array();
     }
     $context->push();
     try {
         $values = $this->sequence->resolve($context, True);
     } catch (VariableDoesNotExist $e) {
         $values = array();
     }
     if ($values === null) {
         $values = array();
     } elseif (is_string($values)) {
         // We convert a string to array to make it iterable.
         $values = str_split($values);
         // TODO Check unicode handling.
     }
     if (!is_array($values) && !$values instanceof Iterator) {
         throw new RuntimeError('Noniterable "' . $values . '" is passed to for loop.');
     }
     $len_values = count($values);
     if ($len_values < 1) {
         $context->pop();
         return $this->nodelist_empty->render($context);
     }
     $nodelist = new NodeList();
     if ($this->is_reversed) {
         $values_ = $values;
         krsort($values_);
         $values = $values_;
         unset($values_);
     }
     $unpack = count($this->loopvars) > 1;
     // Create a forloop value in the context.  We'll update counters on each iteration just below.
     $loop_dict = $context['forloop'] = array('parentloop' => $parentloop);
     foreach ($values as $i => $item) {
         // Shortcuts for current loop iteration number.
         $loop_dict['counter0'] = $i;
         $loop_dict['counter'] = $i + 1;
         // Reverse counter iteration numbers.
         $loop_dict['revcounter'] = $len_values - $i;
         $loop_dict['revcounter0'] = $len_values - $i - 1;
         // Boolean values designating first and last times through loop.
         $loop_dict['first'] = $i == 0;
         $loop_dict['last'] = $i == $len_values - 1;
         $context['forloop'] = array_merge($context['forloop'], $loop_dict);
         $pop_context = False;
         if ($unpack) {
             // If there are multiple loop variables, unpack the item into them.
             $success_ = True;
             try {
                 $unpacked_vars = py_zip($this->loopvars, $item);
             } catch (TypeError $e) {
                 $success_ = False;
             }
             if ($success_) {
                 $pop_context = True;
                 $context->update($unpacked_vars);
             }
         } else {
             $context[$this->loopvars[0]] = $item;
         }
         // In TEMPLATE_DEBUG mode provide source of the node which actually raised the exception
         if (Dja::getSetting('TEMPLATE_DEBUG')) {
             foreach ($this->nodelist_loop as $node) {
                 /** @var $node Node */
                 try {
                     $nodelist[] = $node->render($context);
                 } catch (Exception $e) {
                     if (!py_hasattr($e, 'django_template_source')) {
                         $e->django_template_source = $node->source;
                     }
                     throw $e;
                 }
             }
         } else {
             foreach ($this->nodelist_loop as $node) {
                 $nodelist[] = $node->render($context);
             }
         }
         if ($pop_context) {
             /*
              * The loop variables were pushed on to the context so pop them
              * off again. This is necessary because the tag lets the length
              * of loopvars differ to the length of each set of items and we
              * don't want to leave any vars from the previous loop on the
              * context.
              */
             $context->pop();
         }
     }
     $context->pop();
     return $nodelist->render($context);
 }
Esempio n. 4
0
 /**
  * Returns a compiled Template object for the given template name,
  * handling template inheritance recursively.
  *
  * @param $template_name
  *
  * @return Template
  */
 public static function getTemplate($template_name)
 {
     $self = get_called_class();
     $get_template = function () use($template_name, $self) {
         list($template, $origin) = $self::findTemplate($template_name);
         if (!py_hasattr($template, 'render')) {
             // template needs to be compiled
             $template = $self::getTemplateFromString($template, $origin, $template_name);
         }
         return $template;
     };
     $use_cache = Dja::getSetting('TEMPLATE_CACHE');
     if (!$use_cache) {
         return $get_template();
     }
     $cacher = Dja::getCacheManager();
     if (!($template = $cacher->get($template_name))) {
         $template = $get_template();
         $cacher->set($template_name, $template);
     }
     return $template;
 }