zend-frameworkzend-framework3zend-view

Using Placeholder Viewhelper


I have worked with partials and now I'd like to have something like an info box which shall be filled with additional information.

I'm a bit confused how to give the data to the placeholder.

What I did: I have an additional layoutfile. layout2.phtml

<?php $this->placeholder('content')->captureStart(); ?>

<div class="row">
    <div class="col-md-8">
    <?= $this->content; ?>
    </div>
    <div class="col-md-4">
        <div class="panel panel-default">
          <div class="panel-heading">
            <h3 class="panel-title">additional part info</h3>
          </div>
          <div class="panel-body">
          <strong>Approval Status</strong><p>
            <strong>Alerts</strong> <p>
            there are 
           <?= $this->AnzahlAlerts?> Alerts at the moment<p>
            <strong>MoM</strong><p>
            <p>see MoM here</p>            

          </div>
        </div>
    </div>
</div>

<?php 
  $this->placeholder('content')->captureEnd(); 
  echo $this->partial('layout/layout', 
          ['content'=>$this->placeholder('content')]); 
?>

The placeholderbox will be shown like I wanted.

But I won't get the value of $this->AnzahlAlerts. I thought it must be given to the viewmodell, so I tried as follows:

controller/showAction

  return new ViewModel([
                 'unitid' => $unit,
                 'part' => $part,
                 'dcls' => $this->table->fetchPartDcl($part,$dclid),
                 'pads' => $this->padtable->fetchPadPart($part, $unit),
                  'heritage' => $this->table->getHeritage($part,  $projectid), //$this->unitpartTable->fetchHeritage($part)
                  'AnzahlAlerts' => $this->padtable->countAlert($part)
               ]);

My **onDispatchAction** here for completion:

public function onDispatch(MvcEvent $e)
    {
        $response = parent::onDispatch($e);
        $this->layout()->setTemplate('layout/layout2');
        return $response;
    }

My Questions are, what is the error, and where is the postion to give the value AnzahlAlerts?

EDIT: count records

This is my modelfunction:

public function countAlert($partnumber)
    {
        $statment = "SELECT  count(*) as AnzahlAlerts
        from t_part_alert

        WHERE t_part_alert.Part_Number = '" . $partnumber. "';";
      //  AND  t_unit_part.UnitID =" . $unitid;

        return  $this->tableGateway->adapter->query($statment, "execute");  
}

Just because it my be the problem.


Solution

  • You call and print a partial like so:

    <?= $this->partial('partial/file/alias') ?>
    

    This causes a partial to be rendered within the current partial where you called it. The name in the view_manager config is partial/file/alias.

    If you wanted to pass variables to the partial file, you would have to pass an array as the second parameter, like so:

    <?= $this->partial(
        'partial/file/alias',
        [
            'param1' => 'value1',
            'param2' => 'value2',
        ]
    ) ?>
    

    The keys of the array become parameters in the called partial. So in the partial you can print a variable like so:

    <?= $param1 ?>
    

    When wanting to fill the 2nd partial with data, starting at the controller, you should pass the data you want to the first partial and from there fill the second.


    Another option, the more difficult way, is to pre-render the partials in the Controller and then return the rendered whole from the Controller function.

    Personally, I'm opposed to this as you would then not be separating concerns (viewing vs handling).

    But of course, it's possible ;)


    Full example from Controller into 2nd partial

    class AwesomeController
    {
        public function demoAction()
        {
            // do stuff to create the values
            return [
                'key1' => 'value1',
                'key2' => 'value2',
                'fooKey1' => 'barValue1',
                'fooKey2' => 'barValue2',
            ];
        }
    }
    

    So now there's 4 values. These get passed to demo.phtml. However, the last 2 values are for the sub-partial, so we must call that. We even loop that, because we want to show them more than once!

    <div class="row">
        <div class="col-8 offset-2">
            <table class="table table-striped table-bordered">
                <tr>
                    <th><?= $this->translate('Key 1') ?></th>
                    <td><?= $this->escapeHtml($key1) // <-- Look, the key from Controller is now a variable! This is ZF magic :) ?></td>
                </tr>
                <tr>
                    <th><?= $this->translate('Key 2') ?></th>
                    <td><?= $this->escapeHtml($key2) ?></td>
                </tr>
    
                <?php for ($i = 0; $i < 3; $i++) : ?>
                    <?= $this->partial(
                        'custom/partial', 
                        [
                            'value1' => $fooKey1, // <-- Look, the key from Controller is now a variable! This is ZF magic :) 
                            'value2' => $fooKey2,
                        ]
                    ) ?>
                <?php endfor ?>
            </table>
        </div>
    </div>
    

    Now, the above bit calls for the partial with name custom/partial. This must be registered. Example config below (place in module.config.php from your module):

    'view_manager'    => [
        'template_map'        => [
            'custom/partial' => __DIR__ . '/../view/partials/demo-child.phtml',
            //  -- ^^ name             -- ^^ location
        ],
        'template_path_stack' => [
            __DIR__ . '/../view',
        ],
    ],
    

    File demo-child.phtml

    <tr>
        <th><?= $this->translate('Value 1') ?></th>
        <td><?= $this->escapeHtml($value1) // <-- Look, from above partial - ZF magic :) ?></td>
    </tr>
    <tr>
        <th><?= $this->translate('Value 2') ?></th>
        <td><?= $this->escapeHtml($value2) ?></td>
    </tr>