Search code examples
phalconvolt

Phalcon assign view variable inconsistent


Having a problem getting consistent behavior assigning variables to the view. For example:

In controller:

$this->view->media = Media::findFirst(['groupId=0', 'order' => 'RAND()', 'limit' => 1]);

In view:

        {% if media is defined %}
        <div class="thumbnail">
            <img src="{{ static_url('img/media/thumbs/' ~ media.name) }}" class="img-round">
            <div class="caption">
                <h3>{{ media.title }}</h3>
                <p>{{ media.description }}</p>
            </div>
        </div>
        {% endif %}

Which is parsed like:

        <?php if (isset($media)) { ?>
        <div class="thumbnail">
            <img src="<?php echo $this->url->getStatic('img/media/thumbs/' . $this->media->name); ?>" class="img-round">
            <div class="caption">
                <h3><?php echo $this->media->title; ?></h3>
                <p><?php echo $this->media->description; ?></p>
            </div>
        </div>
        <?php } ?>

The problem is that when the parsed version of the template, $media is not accessible via $this so the isset($media) passes, but the references to $this->media returns nothing.

Any way to force $media to be local in scope?


Solution

  • I think I got it.

    Misbehaviour description

    You have probably declared a media module in your DI(). I was trying quite a lot to reproduce that error, and got it finally when i set a dumb media service among configuration files:

    $di->set('media', function() {
        return new \stdClass();
    });
    

    and than got the same behavior you have - Volt during compilation is not sure, what variable to use and choses $this->media (DI::get('media')) instead of $media or $this->view->media var for obtaining data.

    Solution

    If you dont want to resign from calling you findFirst result under that variable name, you may bypass that by using View in volt directly:

    {% if view.media is defined %}
        <div class="thumbnail">
            <img src="{{ static_url('img/media/thumbs/' ~ view.media.name) }}" class="img-round">
            <div class="caption">
                <h3>{{ view.media.title }}</h3>
                <p>{{ view.media.description }}</p>
            </div>
        </div>
    {% endif %}
    

    it will generate $this->view->media calls instead of $this->media ones.

    +1 on that question.