Feature Request #4383

append() and prepend() for View class

Added by Gah Gneh 4 months ago. Updated 4 months ago.

Status:Feedback Start date:01/04/2012
Priority:Normal Due date:
Assignee:- % Done:

0%

Category:Core
Target version:Unscheduled
Resolution: Points:1

Description

I've done it extending the core classes, but I would like to see it in next releases.

Basically, when doing View::factory('view1')->append(View::factor('view2')) it appends the second view (view2) to the end of the first view (view1) to the end (and all the variables as well), while @View::factory('view1')->prepend(View::factor('view2')) prepends the second view (view2) to the start of the first view (view1)
This way, you can keep D.R.Y. to a maximum, without having to create different views of the same view. It's really useful for views that are requested via AJAX and through GET

view.php - Extended view class (758 Bytes) Gah Gneh, 01/04/2012 12:40 am

view.php - this is the actual version of the extended class (816 Bytes) Gah Gneh, 01/10/2012 07:28 pm

History

Updated by Gah Gneh 4 months ago

Updated by Woody Gilk 4 months ago

  • Category set to Core
  • Status changed from New to Feedback
  • Target version set to Unscheduled

I'm not really sure what the use case for this would be. Can you provide a real-world example?

Updated by Gah Gneh 4 months ago

suppose I have this template:

<!doctype html>
<html>
  <head>
    <?php if (isset($head)) echo $head; ?>
  </head>
  <body>
    <?php echo $content; ?>
  </body>
</html>

and let's say I have 4 D.R.Y. views (that work as partials) with some specific content to them:

view _common_head.php:

<script type="text/javascript">
  $(function(){
    $('table').trigger('zebra');
    $('a.disabled').click(function(){
      $.log(this.href);
    });
    var flash = '<?php if (isset($flash)) echo $flash; ?>';
    if (flash !== ''){  
      $('#flash').text(flash).effect('highlight');
      window.setTimeout(function(){
        $('#flash').fadeOut();
      }, 2000);
    }
  });
</script>

view _ajaxify.php:

<script type="text/javascript">
  $.ajax({
    data: {
  <?php foreach($autoload as $name => $value): ?>
    '<?php echo $name; ?>':'<?php echo $value; ?>',
  <?php endforeach; ?>
   },
   url: '<?php echo $url; ?>'
  });
</script>

view _table.php:

  <table>
    <thead>
      <tr>
      <?php foreach ($header as $head): ?>
        <td><?php echo $head; ?></td>
      <?php endforeach; ?>
      </tr>
    </thead>
    <tbody>
      <?php foreach ($rows as $row): ?>
      <tr>
        <?php foreach ($row as $column): ?>
        <td><?php echo $column ?></td>
        <?php endforeach; ?>
      </tr>
      <?php endforeach; ?>
    </tbody>
  </table>

view _generic_form.php:

  <form action="<?php echo $action; ?>" method="<?php echo $method; ?>">
  <input type="hidden" name="command" value="<?php echo $command; ?>" />
  <?php foreach($inputs as $input):?>
  <p>
    <input type="<?php echo isset($input['type'])?$input['type']:'text'; ?>" value="<?php echo isset($input['value'])?$input['value']:''; ?>" name="<?php echo $input['name']; ?>" />
  </p>
  <?php endforeach; ?>
  <p>
    <input type="submit" value="<?php echo $submit; ?>" />
  </p>
  </form>

sometimes, I need to show only the _table.php, sometimes I need to mix _table.php with _generic_form.php, and sometimes _common_head.php alone or combined with _ajaxify.php, like in the Controller_Index:

class Controller_Index extends Controller_Template {
 /**
  * @var View
  */
  public $template = 'template';

  function action_index(){
    $this->head = View::factory('_common_head');
    $this->content = View::factory('_table')->set(array(
      'header' => array('One','Two','Three'), 
      'rows' => array(
        array('1','2','3'),
        array('4','5','6'),
        array('6','6','0')
      )
    ));
  }

  function action_load(){
    $person = Model::factory('person');
    $this->head = View::factory('_common_head')->append(View::factory('_ajaxify'));
    $this->head->autoload = $person->autoload();
    $this->head->url = url::site('person/fetch');
    $this->head->flash = 'Loading...';
    $this->content = View::factory('_table')->set(array(
      'header' => array('One','Two','Three'), 
      'rows' => $person->rows() 
    ))->append(View::factory('_generic_form', array(
      'submit' => 'Send',
      'action' => '',
      'method' => 'GET',
      'command' => 'create',
      'inputs' => array(
        array(
          'name' => 'password',
          'type' => 'password'
        ),
        array(
          'name' => 'name'
        )
      )  
    )));
  }
}

usually, I use this on my automagic loading of views, that gets loaded to $this->view variable inside the controller, from a class extending the Controller_Template, called AutoTemplate, it loads the view according to the controller name and current action, with corresponding files inside the views folder, like index/load url loads app/views/index/load.action.php (and app/views/index/load.head.php in $this->head) and puts it into $this->view. So, after the $this->view is set, I cannot make it a string to append another view, I need to keep it as a View instance so I can set the variables to it. Hopefully you can understand the usefulness of this.

Updated by Gah Gneh 4 months ago

Also available in: Atom PDF