Changeset 1548

Show
Ignore:
Timestamp:
01/23/07 09:49:45 (2 years ago)
Author:
david
Message:

fire eagle number awesome: new layouting system. look at the sample app to get to know it a bit. of course, you don't have to use preconfigured layouts, and of course you can alter a loaded layout at runtime, e.g. prepend another layer, move stuff around, etc etc. now also fully stream-based templating, so you can load template from ftp, http, memory, whatever you like, as long as you have a stream wrapper for it (which you can write yourself) - or you just implement your own layer class that loads templates from database and caches to disk etc. filter and context support will follow in 1.0. renderers are per layer now, too, and more stuff I can't remember. refs #287

Location:
branches/david-execution_flow
Files:
2 added
27 modified

Legend:

Unmodified
Added
Removed
  • branches/david-execution_flow/samples/app/config/output_types.xml

    r1475 r1548  
    1212+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 
    1313--> 
    14 <configurations> 
     14<configurations xmlns:xi="http://www.w3.org/2001/XInclude"> 
    1515   
    1616  <configuration context="web"> 
     
    3838          </renderer> 
    3939        </renderers> 
     40        <layouts default="default">  
     41          <layout name="default">  
     42            <layers>  
     43              <layer name="content" class="AgaviFileTemplateLayer" />  
     44              <layer name="decorator" class="AgaviFileTemplateLayer">  
     45                <parameters>  
     46                  <parameter name="template">Master</parameter>  
     47                </parameters>  
     48              </layer>  
     49            </layers>  
     50          </layout>  
     51        </layouts>  
    4052        <parameters> 
    4153          <parameter name="Content-Type">text/html; charset=UTF-8</parameter> 
     
    4456       
    4557      <output_type name="xhtml"> 
    46         <renderers default="php"> 
    47           <renderer name="php" class="AgaviPhpRenderer"> 
    48             <parameters> 
    49               <parameter name="assigns"> 
    50                 <parameters> 
    51                   <parameter name="routing">r</parameter> 
    52                   <parameter name="request">req</parameter> 
    53                   <parameter name="controller">ctl</parameter> 
    54                   <parameter name="user">usr</parameter> 
    55                   <parameter name="translation_manager">tm</parameter> 
    56                 </parameters> 
    57               </parameter> 
    58             </parameters> 
    59           </renderer> 
    60         </renderers> 
     58        <xi:include href="#xpointer(//configurations/configuration[@context='web']/output_types/output_type[@name='html']/renderers)" /> 
     59        <xi:include href="#xpointer(//configurations/configuration[@context='web']/output_types/output_type[@name='html']/layouts)" /> 
    6160        <parameters> 
    6261          <parameter name="Content-Type">application/xhtml+xml; charset=UTF-8</parameter> 
  • branches/david-execution_flow/samples/app/modules/Default/views/Error404SuccessView.class.php

    r1505 r1548  
    2626  public function execute(AgaviParameterHolder $parameters) 
    2727  { 
    28     // set our template 
    29     $this->addLayer('content', 'Error404Success'); 
    30     $this->addLayer('decorator', 'Master'); 
     28    $this->loadLayout(); 
    3129 
    3230    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/IndexSuccessView.class.php

    r1475 r1548  
    2626  public function execute(AgaviParameterHolder $parameters) 
    2727  { 
    28     // set our template 
    29     $this->addLayer('content', 'IndexSuccess'); 
    30     $this->addLayer('decorator', 'Master'); 
     28    $this->loadLayout(); 
    3129     
    3230    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/LoginInputView.class.php

    r1475 r1548  
    2626  public function execute(AgaviParameterHolder $parameters) 
    2727  { 
    28     // set our template 
    29     $this->addLayer('content', 'LoginInput'); 
    30     $this->addLayer('decorator', 'Master'); 
     28    $this->loadLayout(); 
    3129     
    3230    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/LoginSuccessView.class.php

    r1475 r1548  
    5656    } 
    5757     
    58     // set our template 
    59     $this->addLayer('content', 'LoginInput'); 
    60     $this->addLayer('decorator', 'Master'); 
     58    $this->loadLayout(); 
    6159     
    6260    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/LogoutSuccessView.class.php

    r1475 r1548  
    2626  public function execute(AgaviParameterHolder $parameters) 
    2727  { 
    28     // set our template 
    29     $this->addLayer('content', 'LogoutSuccess'); 
    30     $this->addLayer('decorator', 'Master'); 
     28    $this->loadLayout(); 
    3129     
    3230    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/ModuleDisabledSuccessView.class.php

    r1505 r1548  
    2626  public function execute(AgaviParameterHolder $parameters) 
    2727  { 
    28     // set our template 
    29     $this->addLayer('content', 'Error404Success'); 
    30     $this->addLayer('decorator', 'Master'); 
     28    $this->loadLayout(); 
    3129 
    3230    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/SearchEngineSpamSuccessView.class.php

    r1475 r1548  
    1010  public function execute(AgaviParameterHolder $parameters) 
    1111  { 
    12     // set our template 
    13     $this->addLayer('content', 'SearchEngineSpamSuccess'); 
    14     $this->addLayer('decorator', 'Master'); 
     12    $this->loadLayout(); 
    1513     
    1614    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/Secure1SuccessView.class.php

    r1475 r1548  
    1010  public function execute(AgaviParameterHolder $parameters) 
    1111  { 
    12     // set our template 
    13     $this->addLayer('content', 'Secure1Success'); 
    14     $this->addLayer('decorator', 'Master'); 
     12    $this->loadLayout(); 
    1513     
    1614    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/Secure2SuccessView.class.php

    r1475 r1548  
    1010  public function execute(AgaviParameterHolder $parameters) 
    1111  { 
    12     // set our template 
    13     $this->addLayer('content', 'Secure2Success'); 
    14     $this->addLayer('decorator', 'Master'); 
     12    $this->loadLayout(); 
    1513     
    1614    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/SecureSuccessView.class.php

    r1505 r1548  
    2626  public function execute(AgaviParameterHolder $parameters) 
    2727  { 
    28     // set our template 
    29     $this->addLayer('content', 'Error404Success'); 
    30     $this->addLayer('decorator', 'Master'); 
     28    $this->loadLayout(); 
    3129 
    3230    // set the content type 
  • branches/david-execution_flow/samples/app/modules/Default/views/UnavailableSuccessView.class.php

    r1505 r1548  
    2626  public function execute(AgaviParameterHolder $parameters) 
    2727  { 
    28     // set our template 
    29     $this->addLayer('content', 'Error404Success'); 
    30     $this->addLayer('decorator', 'Master'); 
     28    $this->loadLayout(); 
    3129 
    3230    // set the content type 
  • branches/david-execution_flow/src/buildtools/code_templates/View.class.php.tmpl

    r908 r1548  
    99  public function execute(AgaviParameterHolder $parameters) 
    1010  { 
    11     // set our template 
    12     $this->setTemplate('%%ACTION_PATH%%%%VIEW%%'); 
    13  
    1411    // set the title 
    1512    $this->setAttribute('_title', '%%ACTION%% Action'); 
  • branches/david-execution_flow/src/buildtools/code_templates/config/output_types.xml

    r1353 r1548  
    4848 
    4949      <output_type name="html"> 
    50         <renderer class="AgaviPhpRenderer"> 
    51           <parameters> 
    52             <parameter name="assigns"> 
    53               <parameters> 
    54                 <parameter name="routing">ro</parameter> 
    55                 <parameter name="request">rq</parameter> 
    56                 <parameter name="controller">ct</parameter> 
    57                 <parameter name="user">us</parameter> 
    58                 <parameter name="translation_manager">tm</parameter> 
    59               </parameters> 
    60             </parameter> 
    61           </parameters> 
    62         </renderer> 
     50        <renderers default="php"> 
     51          <renderer name="php" class="AgaviPhpRenderer"> 
     52            <parameters> 
     53              <parameter name="assigns"> 
     54                <parameters> 
     55                  <parameter name="routing">ro</parameter> 
     56                  <parameter name="request">rq</parameter> 
     57                  <parameter name="controller">ct</parameter> 
     58                  <parameter name="user">us</parameter> 
     59                  <parameter name="translation_manager">tm</parameter> 
     60                </parameters> 
     61              </parameter> 
     62            </parameters> 
     63          </renderer> 
     64        </renderers> 
     65        <layouts default="default">  
     66          <layout name="default">  
     67            <layers> 
     68              <layer name="content" class="AgaviFileTemplateLayer" />  
     69            </layers>  
     70          </layout>  
     71        </layouts>  
    6372        <parameters> 
    64           <parameter name="Content-Type">text/html</parameter> 
     73          <parameter name="Content-Type">text/html; charset=UTF-8</parameter> 
    6574        </parameters> 
    6675      </output_type> 
  • branches/david-execution_flow/src/config/AgaviOutputTypeConfigHandler.class.php

    r1477 r1548  
    7575      foreach($cfg->output_types as $outputType) { 
    7676        $outputTypeName = $outputType->getAttribute('name'); 
    77         $data[$outputTypeName] = isset($data[$outputTypeName]) ? $data[$outputTypeName] : array('parameters' => array(), 'default_renderer' => null, 'renderers' => array(), 'exception_template' => null); 
     77        $data[$outputTypeName] = isset($data[$outputTypeName]) ? $data[$outputTypeName] : array('parameters' => array(), 'default_renderer' => null, 'renderers' => array(), 'layouts' => array(), 'default_layout' => null, 'exception_template' => null); 
    7878        if(isset($outputType->renderers)) { 
    7979          foreach($outputType->renderers as $renderer) { 
    8080            $rendererName = $renderer->getAttribute('name'); 
    81             $data[$outputTypeName]['renderers'][$rendererName] = array('instance' => null, 'class' => null, 'extension' => null, 'parameters' => array()); 
     81            $data[$outputTypeName]['renderers'][$rendererName] = array('instance' => null, 'class' => null, 'parameters' => array()); 
    8282            $data[$outputTypeName]['renderers'][$rendererName]['class'] = $renderer->getAttribute('class'); 
    83             $data[$outputTypeName]['renderers'][$rendererName]['extension'] = $renderer->getAttribute('extension'); 
    8483            $data[$outputTypeName]['renderers'][$rendererName]['parameters'] = $this->getItemParameters($renderer, $data[$outputTypeName]['renderers'][$rendererName]['parameters']); 
    8584          } 
    8685          $data[$outputTypeName]['default_renderer'] = $outputType->renderers->getAttribute('default'); 
     86        } 
     87        if(isset($outputType->layouts)) { 
     88          foreach($outputType->layouts as $layout) { 
     89            $layoutName = $layout->getAttribute('name'); 
     90            $data[$outputTypeName]['layouts'][$layoutName] = array('layers' => array()); 
     91            if(isset($layout->layers)) { 
     92              foreach($layout->layers as $layer) { 
     93                $layerName = $layer->getAttribute('name'); 
     94                $data[$outputTypeName]['layouts'][$layoutName]['layers'][$layerName] = array('class' => null, 'renderer' => null, 'parameters' => array()); 
     95                $data[$outputTypeName]['layouts'][$layoutName]['layers'][$layerName]['class'] = $layer->getAttribute('class'); 
     96                if(($rendererName = $layer->getAttribute('renderer')) !== null) { 
     97                  if(!isset($rendererName, $data[$outputTypeName]['renderers'])) { 
     98                    throw new AgaviConfigurationException('Layout "' . $layoutName . '" specifies layer "' . $layerName . '" with non-defined renderer "' . $rendererName . '".'); 
     99                  } 
     100                  $data[$outputTypeName]['layouts'][$layoutName]['layers'][$layerName]['renderer'] = $rendererName; 
     101                } 
     102                $data[$outputTypeName]['layouts'][$layoutName]['layers'][$layerName]['parameters'] = $this->getItemParameters($layer, $data[$outputTypeName]['layouts'][$layoutName]['layers'][$layerName]['parameters']); 
     103              } 
     104            } 
     105          } 
     106          $data[$outputTypeName]['default_layout'] = $outputType->layouts->getAttribute('default'); 
    87107        } 
    88108        if($outputType->hasAttribute('exception_template')) { 
     
    101121      $code[] = implode("\n", array( 
    102122        '$ot = new AgaviOutputType();', 
    103         '$ot->initialize($this->context, ' . var_export($outputType['parameters'], true) . ', ' . var_export($outputTypeName, true) . ', ' . var_export($outputType['renderers'], true) . ', ' . var_export($outputType['default_renderer'], true) . ', ' . var_export($outputType['exception_template'], true) . ');', 
     123        '$ot->initialize($this->context, ' . var_export($outputType['parameters'], true) . ', ' . var_export($outputTypeName, true) . ', ' . var_export($outputType['renderers'], true) . ', ' . var_export($outputType['default_renderer'], true) . ', ' . var_export($outputType['layouts'], true) . ', ' . var_export($outputType['default_layout'], true) . ', ' . var_export($outputType['exception_template'], true) . ');', 
    104124        '$this->outputTypes["' . $outputTypeName . '"] = $ot;', 
    105125      )); 
  • branches/david-execution_flow/src/config/defaults/autoload.xml

    r1530 r1548  
    203203      <autoload name="AgaviSetValidator">%core.agavi_dir%/validator/AgaviSetValidator.class.php</autoload> 
    204204      <autoload name="AgaviStringValidator">%core.agavi_dir%/validator/AgaviStringValidator.class.php</autoload> 
     205       
     206      <!-- agavi/view --> 
     207      <autoload name="AgaviFileTemplateLayer">%core.agavi_dir%/view/AgaviFileTemplateLayer.class.php</autoload> 
     208      <autoload name="AgaviStreamTemplateLayer">%core.agavi_dir%/view/AgaviStreamTemplateLayer.class.php</autoload> 
    205209    </autoloads> 
    206210  </configuration> 
  • branches/david-execution_flow/src/config/xsd/output_types.xsd

    r1475 r1548  
    3030      <xs:group ref="parameters" /> 
    3131      <xs:element name="renderers" type="renderers" minOccurs="0" /> 
     32      <xs:element name="layouts" type="layouts" minOccurs="0" /> 
    3233    </xs:sequence> 
    3334    <xs:attribute name="name" type="php_label" use="required" /> 
     
    4748    <xs:attribute name="name" type="php_label" use="required" /> 
    4849    <xs:attribute name="class" type="php_label" use="required" /> 
    49     <xs:attribute name="extension" type="xs:string" /> 
     50  </xs:complexType> 
     51 
     52  <xs:complexType name="layouts"> 
     53    <xs:sequence> 
     54      <xs:element name="layout" type="layout" maxOccurs="unbounded" /> 
     55    </xs:sequence> 
     56    <xs:attribute name="default" type="php_label" use="required" /> 
     57  </xs:complexType> 
     58  <xs:complexType name="layout"> 
     59    <xs:sequence> 
     60      <xs:element name="layers" type="layers" minOccurs="0" /> 
     61    </xs:sequence> 
     62    <xs:attribute name="name" type="php_label" use="required" /> 
     63  </xs:complexType> 
     64 
     65  <xs:complexType name="layers"> 
     66    <xs:sequence> 
     67      <xs:element name="layer" type="layer" maxOccurs="unbounded" /> 
     68    </xs:sequence> 
     69  </xs:complexType> 
     70  <xs:complexType name="layer"> 
     71    <xs:sequence> 
     72      <xs:group ref="parameters" /> 
     73    </xs:sequence> 
     74    <xs:attribute name="name" type="php_label" use="required" /> 
     75    <xs:attribute name="class" type="php_label" use="required" /> 
     76    <xs:attribute name="renderer" type="php_label" /> 
    5077  </xs:complexType> 
    5178 
  • branches/david-execution_flow/src/controller/AgaviOutputType.class.php

    r1477 r1548  
    4949   
    5050  /** 
     51   * @var        array An array of configured layouts. 
     52   */ 
     53  protected $layouts = array(); 
     54   
     55  /** 
     56   * @var        string The name of the default layout, if set. 
     57   */ 
     58  protected $defaultLayout = null; 
     59   
     60  /** 
    5161   * @var        string The name of the exception template for this output type. 
    5262   */ 
     
    6272   * @since      0.11.0 
    6373   */ 
    64   public function initialize(AgaviContext $context, array $parameters, $name, array $renderers, $defaultRenderer, $exceptionTemplate = null) 
     74  public function initialize(AgaviContext $context, array $parameters, $name, array $renderers, $defaultRenderer, array $layouts, $defaultLayout, $exceptionTemplate = null) 
    6575  { 
    6676    $this->context = $context; 
     
    7383     
    7484    $this->defaultRenderer = $defaultRenderer; 
     85     
     86    $this->layouts = $layouts; 
     87     
     88    $this->defaultLayout = $defaultLayout; 
    7589     
    7690    $this->exceptionTemplate = $exceptionTemplate; 
     
    151165   
    152166  /** 
     167   * Get a layout. 
     168   * 
     169   * @param      The optional name of the layout to fetch. 
     170   * 
     171   * @return     array An array of layout information. 
     172   * 
     173   * @author     David Zuelke <dz@bitxtender.com> 
     174   * @since      0.11.0 
     175   */ 
     176  public function getLayout($name = null) 
     177  { 
     178    if($name === null) { 
     179      $name = $this->defaultLayout; 
     180    } 
     181     
     182    if(isset($this->layouts[$name])) { 
     183      return $this->layouts[$name]; 
     184    } else { 
     185      throw new AgaviException('Unknown layout "' . $name . '"'); 
     186    } 
     187  } 
     188   
     189  /** 
    153190   * Get the exception template filename for this renderer. 
    154191   * 
  • branches/david-execution_flow/src/filter/AgaviExecutionFilter.class.php

    r1535 r1548  
    371371          $output = array(); 
    372372          $nextOutput = null; 
    373           foreach($viewInstance->getLayers() as $layerName => $layer) { 
     373          foreach($viewInstance->getLayers() as $layer) { 
    374374            foreach($layer->getSlots() as $slotName => $slotContainer) { 
    375375              $slotResponse = $slotContainer->execute(); 
     
    383383            $nextOutput = $layer->getRenderer()->render($layer, $attributes, $output); 
    384384            $output = array(); 
    385             $output[$layerName] = $nextOutput; 
     385            $output[$layer->getName()] = $nextOutput; 
    386386          } 
    387387          $response->setContent($nextOutput); 
  • branches/david-execution_flow/src/renderer/AgaviPhpRenderer.class.php

    r1475 r1548  
    3333   *                    including the dot. 
    3434   */ 
    35   protected $extension = '.php'; 
    36  
     35  protected $defaultExtension = '.php'; 
     36   
    3737  /** 
    38    * Retrieve the template engine associated with this view. 
    39    * 
    40    * Note: This will return null because PHP itself has no engine reference. 
    41    * 
    42    * @return     null 
     38   * @var        AgaviTemplateLayer Temporary storage for the template layer, 
     39   *                                used during rendering. 
    4340   */ 
    44   public function getEngine() 
    45   { 
    46     return null; 
    47   } 
    48  
     41  protected $_layer = null; 
     42   
    4943  /** 
    50    * Reset the engine for re-use 
    51    * 
    52    * @author     David Zuelke <dz@bitxtender.com> 
    53    * @since      0.11.0 
     44   * @var        array Temporary storage for the template layer, used during 
     45   *                   rendering. 
    5446   */ 
    55   protected function reset() 
    56   { 
    57     // nothing needs to be done for PHP 
    58   } 
     47  protected $_attributes = null; 
     48   
     49  /** 
     50   * @var        array Temporary storage for the template layer, used during 
     51   *                   rendering. 
     52   */ 
     53  protected $_slots = null; 
    5954   
    6055  /** 
     
    6762  { 
    6863    // DO NOT USE VARIABLES IN HERE, THEY MIGHT INTERFERE WITH TEMPLATE VARS 
     64    $this->_layer = $layer; 
     65    $this->_attributes =& $attributes; 
     66    $this->_slots =& $slots; 
     67    unset($layer, $attributes, $slots); 
    6968     
    7069    if($this->extractVars) { 
    71       extract($attributes, EXTR_REFS | EXTR_PREFIX_INVALID, '_'); 
     70      extract($this->_attributes, EXTR_REFS | EXTR_PREFIX_INVALID, '_'); 
    7271    } else { 
    73       ${$this->varName} =& $attributes; 
     72      ${$this->varName} =& $this->_attributes; 
    7473    } 
    7574     
    7675    if($this->extractSlots === true || ($this->extractVars && $this->extractSlots !== false)) { 
    77       extract($slots, EXTR_REFS | EXTR_PREFIX_INVALID, '_'); 
     76      extract($this->_slots, EXTR_REFS | EXTR_PREFIX_INVALID, '_'); 
    7877    } else { 
    7978      if(!isset(${$this->slotsVarName})) { 
    8079        ${$this->slotsVarName} = array(); 
    8180      } 
    82       ${$this->slotsVarName} = array_merge(${$this->slotsVarName}, $slots); 
     81      ${$this->slotsVarName} = array_merge(${$this->slotsVarName}, $this->_slots); 
    8382    } 
    8483     
    85     $collisions = array_intersect(array_keys($this->assigns), array_keys($attributes)); 
     84    $collisions = array_intersect(array_keys($this->assigns), array_keys($this->_attributes)); 
    8685    if(count($collisions)) { 
    8786      throw new AgaviException('Could not import system objects due to variable name collisions ("' . implode('", "', $collisions) . '" already in use).'); 
    8887    } 
     88    unset($collisions); 
    8989     
    9090    extract($this->assigns); 
     
    9292    ob_start();