示例#1
0
文件: base.php 项目: idlesign/dja
 /**
  * @param Context $context
  *
  * @return SafeString
  */
 public function render_($context)
 {
     return $this->nodelist->render($context);
 }
示例#2
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);
 }