avasin
avasin

Reputation: 9726

It is possible to get Phalcon\Mvc\View rendered output in variable?

I need to give back json object, that has property 'html' with rendered action. Is it possible to do natively with Phalcon vew?

Example:

$posts = NewsPost::find(['limit' => 10]);
$view = new Phalcon\Mvc\View();
$view->setVar('posts', $posts);
$view->setMainView('news/posts'); // not sure if this is correct

// retrieve some data ...
$response = [
    'html' => $view->render(),
    'somedata' => 'somevalues',
    ....
];

P.S. Question regarding phalcon php framework: http://docs.phalconphp.com/en/latest/api/Phalcon_Mvc_View.html

Upvotes: 5

Views: 10591

Answers (5)

Dror Dromi
Dror Dromi

Reputation: 163

Here is a class, based on View, rendered into HTML or JSON (Api call).

use \Phalcon\Mvc\View;

class ApiView extends View
{
    const OUTPUT_DEFAULT = 0;
    const OUTPUT_JSON = 1;
    public $output_type = self::OUTPUT_DEFAULT;

    public function setOutputJson()
    {
        $this->output_type = ApiView::OUTPUT_JSON;
    }

    public function setOutputDefault() {
        $this->output_type = ApiView::OUTPUT_DEFAULT;
    }

    public function render($controllerName, $actionName, $params = null)
    {
        if ($this->output_type === ApiView::OUTPUT_JSON)
        {
            echo json_encode($this->getParamsToView());
            $this->disable();
        }
        parent::render($controllerName, $actionName, $params);
        if ($this->output_type === GollgiView::OUTPUT_JSON) {
            header("Content-type: application/json, 'UTF-8')");
        }
    }

    public function getOutputType() {
        return $this->output_type;
    }
}

Change config/service.php to create by default ApiView

/**
 * Setting up the view component
 */
$di->setShared('view', function () use ($config) {
     $view = new ApiView();
     $view->setViewsDir($config->application->viewsDir);
     $view->registerEngines(['.phtml' => 'Phalcon\Mvc\View\Engine\Php']);
     return $view;
});

In the controller you can decide what type of output you wish for

if ($this->request->has('api')) {
    $this->view->setOutputJson();
}

Upvotes: 0

Sorin
Sorin

Reputation: 19

There is a simple solution that I'm using it (in any part of the app I used in a model) : 1. Load the view object from DI 2. Use getRender with parameters

        // Get the view from DI
        $theView = $this->getDi()->getShared('view');
        // Load the text into variable
        $emailText = $theView->getRender('emails', $emailTemplate, $emailData, function($theView) {
            $theView->setRenderLevel(\Phalcon\Mvc\View::LEVEL_ACTION_VIEW);
        });

Upvotes: 0

GoryGreg
GoryGreg

Reputation: 41

$view = new Phalcon\Mvc\View();

$view->setVar('posts', $posts);

$view->start();
$view->render(); //Pass a controller/action as parameters if required
$view->finish();

// retrieve some data ...
$response = [
    'html' => $view->getContent(),
    'somedata' => 'somevalues',
    ....
];

Don't forget to use

$view->setViewsDir(APP_PATH . '/app/views/');

Otherwise you might get a empty string returned.

Upvotes: 0

twistedxtra
twistedxtra

Reputation: 2699

The output buffering needs to be started first:

$view = new Phalcon\Mvc\View();

$view->setVar('posts', $posts);

$view->start();
$view->render(); //Pass a controller/action as parameters if required
$view->finish();

// retrieve some data ...
$response = [
    'html' => $view->getContent(),
    'somedata' => 'somevalues',
    ....
];

Upvotes: 7

Nikolaos Dimopoulos
Nikolaos Dimopoulos

Reputation: 11485

Try this

$posts = NewsPost::find(['limit' => 10]);
$view = new \Phalcon\Mvc\View();
$view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_LAYOUT);
$view->setVar('posts', $posts);
$viewData = $view->render('news', 'posts');

// retrieve some data ...
$response = [
    'html' => $viewData,
    'somedata' => 'somevalues',
    ....
];

Upvotes: 1

Related Questions