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

Override the default view not working

Hi,

I'm having a problem overriding the default view thats being rendered. I have tried using :

$this->view->pick('example');

here is my full code:

config.php

<?php
/*
 * Modified: prepend directory path of current file, because of this file own different ENV under between Apache and command line.
 * NOTE: please remove this comment.
 */
defined('BASE_PATH') || define('BASE_PATH', getenv('BASE_PATH') ?: realpath(dirname(__FILE__) . '/../..'));
defined('APP_PATH') || define('APP_PATH', BASE_PATH . '/app');
return new \Phalcon\Config([
    'database' => [
        'adapter'     => 'Mysql',
        'host'        => 'localhost',
        'username'    => 'root',
        'password'    => '',
        'dbname'      => 'example',
        'charset'     => 'utf8',
    ],
    'application' => [
        'appDir'         => APP_PATH . '/',
        'controllersDir' => APP_PATH . '/controllers/',
        'modelsDir'      => APP_PATH . '/models/',
        'migrationsDir'  => APP_PATH . '/migrations/',
        'viewsDir'       => APP_PATH . '/views/example/',
        'pluginsDir'     => APP_PATH . '/plugins/',
        'libraryDir'     => APP_PATH . '/library/',
        'cacheDir'       => BASE_PATH . '/cache/',
        // This allows the baseUri to be understand project paths that are not in the root directory
        // of the webpspace.  This will break if the public/index.php entry point is moved or
        // possibly if the web server rewrite rules are changed. This can also be set to a static path.
        'baseUri'        => preg_replace('/public([\/\\\\])index.php$/', '', $_SERVER["PHP_SELF"]),
    ]
]);

loader.php

<?php
$loader = new \Phalcon\Loader();
/**
 * We're a registering a set of directories taken from the configuration file
 */
$loader->registerDirs(
    [
        $config->application->controllersDir,
        $config->application->modelsDir
    ]
)->register();

services.php

<?php

use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Php as PhpEngine;
use Phalcon\Mvc\Url as UrlResolver;
use Phalcon\Mvc\View\Engine\Volt as VoltEngine;
use Phalcon\Mvc\Model\Metadata\Memory as MetaDataAdapter;
use Phalcon\Session\Adapter\Files as SessionAdapter;
use Phalcon\Flash\Direct as Flash;

/**
 * Shared configuration service
 */
$di->setShared('config', function () {
    return include APP_PATH . "/config/config.php";
});

/**
 * The URL component is used to generate all kind of urls in the application
 */
$di->setShared('url', function () {
    $config = $this->getConfig();

    $url = new UrlResolver();
    $url->setBaseUri($config->application->baseUri);

    return $url;
});

/**
 * Setting up the view component
 */
$di->setShared('view', function () {
    $config = $this->getConfig();

    $view = new View();
    $view->setDI($this);
    $view->setViewsDir($config->application->viewsDir);

    $view->registerEngines([
        '.volt' => function ($view) {
            $config = $this->getConfig();

            $volt = new VoltEngine($view, $this);

            $volt->setOptions([
                'compiledPath' => $config->application->cacheDir,
                'compiledSeparator' => '_'
            ]);

            return $volt;
        },
        '.phtml' => PhpEngine::class

    ]);

    return $view;
});

/**
 * Database connection is created based in the parameters defined in the configuration file
 */
$di->setShared('db', function () {
    $config = $this->getConfig();

    $class = 'Phalcon\Db\Adapter\Pdo\\' . $config->database->adapter;
    $params = [
        'host'     => $config->database->host,
        'username' => $config->database->username,
        'password' => $config->database->password,
        'dbname'   => $config->database->dbname,
        'charset'  => $config->database->charset
    ];

    if ($config->database->adapter == 'Postgresql') {
        unset($params['charset']);
    }

    $connection = new $class($params);

    return $connection;
});

/**
 * If the configuration specify the use of metadata adapter use it or use memory otherwise
 */
$di->setShared('modelsMetadata', function () {
    return new MetaDataAdapter();
});

/**
 * Register the session flash service with the Twitter Bootstrap classes
 */
$di->set('flash', function () {
    return new Flash([
        'error'   => 'alert alert-danger',
        'success' => 'alert alert-success',
        'notice'  => 'alert alert-info',
        'warning' => 'alert alert-warning'
    ]);
});

/**
 * Start the session the first time some component request the session service
 */
$di->setShared('session', function () {
    $session = new SessionAdapter();
    $session->start();

    return $session;
});

ExampleController.php

<?php

class ExampleController extends ControllerBase
{

    public function indexAction()
    {
      // $result = Test::findFirst([
      //   'columns'    => 'id, name',
      //   'conditions' => 'active = ?1',
      //   'bind'       => [
      //       1=> 1,
      //   ]
      // ])->toArray();
$this->view->pick('example');
    }
}

Currently the ExampleController is still outputting the index.volt file, I would like to output the example.volt file instead. I have tried clearing the cache as well any help with thi would be appreciated.

Thanks



6.6k

Hi,

Just tried using:

$this->view->setMainView("example");

And it worked with that but is this the ideal way way of changing the default view?

Thans

hey you have to use full path from viewDir like this $this->view->pick('example/index');

Good luck



6.6k

Hi, Thanks for the response, I changed the file structure slightly for the views, my config is:

'viewsDir' => APP_PATH . '/views/example/'

So based on this config, the file that I wish to call would normally be located at:

views->example->example->index.volt

But I would like the structure as:

views->example->example.volt

Hence when I call:

$this->view->setMainView("example");

The view is loaded but If I try:

$this->view->pick('example');

The default home page view is loaded (index.volt), do you know why this is occurring? And also is there any techincal difference between these two commands:

$this->view->pick('example'); and $this->view->setMainView("example");

Thanks for helping a noob :)



32.2k
Accepted
answer

pick("dirName/viewName") Choose a different view to render instead of last-controller/last-action

setMainView("viewName") Sets default view name. Must be a file without extension in the views directory

Read view docs and api view

Good luck

edited Mar '18

What about using partial ? Including example partial in your index view to keep the usual logic ?



6.6k

Thanks, for the answers I have decided to go with pick("dirName/viewName") I changed 'viewsDir' => APP_PATH . '/views/', so now I have a dynamic value for dirName which gives me the option to switch themes.

Yes remember that Phalcon views in general do a Controller View, then a Layout View, then a Main View.

pick() will choose a controller view, but the main view will still render, and if you don't have getContent() in there it won't display what was done in the Controller view.

So the examples above of selecting setMainView() will change the final view in the chain.