We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Dynamic keys in volt partial

Hello,

I'm using Phalcon 2.0.10 and facing a problem with the volt engine. Is there a way to use dynamic keys for the options in a partial call? I tried the following without success:

{{ partial('shared/pagetitle', ['title' : t._('My title'), 'breadcrumb': ['/link/to/' ~ model.id: t._('My second title')]]) }}

or

{% set linkto = '/link/to/' ~ model.id %}
{{ partial('shared/pagetitle', ['title' : t._('My title'), 'breadcrumb': [linkto: t._('My second title')]]) }}

or

{% set breadcrumb = ['/link/to/' ~ model.id: t._('My second title')] %}
{{ partial('shared/pagetitle', ['title' : t._('My title'), 'breadcrumb': breadcrumb]) }}

or

{% set linkto = '/link/to/' ~ model.id %}
{% set breadcrumb = [linkto: t._('My second title')] %}
{{ partial('shared/pagetitle', ['title' : t._('My title'), 'breadcrumb': breadcrumb]) }}

This is the error message i get:

Phalcon\Mvc\View\Exception: Syntax error, unexpected token COLON in XYZ

Even with a filter it doesn't work (is $this the real context from the view?) or is just to complex when using $exprArgs:

$voltcompiler->addFunction('breadcrumb', function ($resolvedArgs, $exprArgs) {
    var_dump($resolvedArgs, $exprArgs);
    // $resolvedArgs => array('/link/to/' . $this->model->id, $this->t->_('My second title'))
    /* $exprArgs => 
    array (size=1)
    0 => 
      array (size=3)
        'expr' => 
          array (size=4)
            'type' => int 360
            'left' => 
              array (size=2)
                0 => 
                  array (size=3)
                    'expr' => 
                      array (size=5)
                        ....
     */
});

// usage in volt template
{% set bc = breadcrumb(['/link/to/' ~ model.id, t._('My second title')])
{{ partial('shared/pagetitle', ['title' : t._('My title'), 'breadcrumb': bc]) }}

Anyone has some suggestions how i can resolve this?



1.6k
edited May '16

I think I found a solution. It is more a dirty hack than a solution, but it works:

{% set json = '{"/link/to/' ~ model.id ~ '": ' ~ t._('My second title')|json_encode ~ '}' %}
{% set breadcrumb = json|json_decode %}
{{ partial('shared/pagetitle', ['title': t._('My title'), 'breadcrumb': breadcrumb]) }}

Any other suggestions?

edited Jun '16

Are you looking for this?

{% include 'shared/pagetitle' with ['title': t._('My title'), 'breadcrumb' : breadcrumb ] %}

shared/pagetitle.volt

<title>{{ title }}</title>
{{ breadcrumb }}
edited Jun '16

Maybe something more complex like this. This is a copy paste from a website I built a while ago, this is the controller for the manual

class ManualController extends ControllerBase
{
    private $crumbs = array();

    public function initialize()
    {
        $this->view->setTemplateAfter('main');
        Phalcon\Tag::setTitle('Manual');
        $this->addCrumb("Shadow Realm", "");
        parent::initialize();
    }

    private function addCrumb($name, $link){
        $this->crumbs[] = new crumb($name, $link);
        $this->view->crumbs = $this->crumbs;
    }

    public function indexAction($arg1=false, $arg2=false, $arg3=false)
    {
        $path = "";
        if($arg1 && $arg2 && $arg3){
            $path .= $arg1;
            $this->addCrumb(ucfirst($arg1), $path);
            $path .= "/".$arg2;
            $this->addCrumb(ucfirst($arg2), $path);
            $path .= "/".$arg3;
            $this->addCrumb(ucfirst($arg3), $path);
        }else if($arg1 && $arg2){
            $path .= $arg1;
            $this->addCrumb(ucfirst($arg1), $path);
            $path .= "/".$arg2;
            $this->addCrumb(ucfirst($arg2), $path);
        }else if($arg1){
            $path .= $arg1;
            $this->addCrumb(ucfirst($arg1), $path);
        }
        //set to a different view if we have some args.
        if($path !== ""){
            if(!file_exists(__DIR__ . "/../views/manual/".$path.".volt")){
                $path = "missing";
            }
            $this->view->pick("manual/".$path);
        }else{

        }
        //makes writing link_to easier.
        $this->view->m = "manual/";
    }

}

class crumb{
    public $name = "";
    public $link = "";

    public function __construct($name, $link){
        $this->name = $name;
        $this->link = $link;
    }   
}

layouts/manual.volt

<div class='panel panel-default'>
    <div class='panel-heading'>
        <ol class="breadcrumb" style='margin-bottom:0px;padding-bottom:0px;padding-top:0px;'>
            {% set i = 0 %}
            {% for crumb in crumbs %}
                {% set i = i + 1 %}
                {% if i < crumbs|length %}
                <li>
                    {{ link_to("manual/"~crumb.link, crumb.name) }}
                {% else %}
                <li class="active">
                    {{ crumb.name }}
                {% endif %}
                </li>
            {% endfor %}
        </ol>
    </div>
    <div class='panel-body'>
        {{ content() }}
    </div>
</div>