Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setDI for a view does not set iself as a 'view' in DI container #235

Closed
eugene-p opened this issue Dec 5, 2012 · 3 comments
Closed

setDI for a view does not set iself as a 'view' in DI container #235

eugene-p opened this issue Dec 5, 2012 · 3 comments
Labels
new feature request Planned Feature or New Feature Request
Milestone

Comments

@eugene-p
Copy link

eugene-p commented Dec 5, 2012

Tried in version 0.7.0
Happens when Volt used separately from application

Setup:

  • index.php
  • views
    • index
      • index.html
    • layout
      • main.html

index.php

    $di = new Phalcon\DI\FactoryDefault();
    $di->set('volt', function ($view, $di){
         return new Phalcon\Mvc\View\Engine\Volt($view, $di);
    });

    $view = new \Phalcon\Mvc\View();
    $view->setViewsDir('views/');
    $view->registerEngines(array(
        '.html' => 'volt'
    ));
    $view->setDi($di);                                                                                                                                                                                                                            
    $view->start();
    $view->render('index', 'index');
    $view->finish();
    echo $view->getContent();

views/index/index.html

<h1>Main</h1>                                                                                                                                                                                                                                 
{% block content %}
    Not index
{% endblock %}

views/index/index.html

{% extends "layouts/main.html" %}                                                                                                                                                                                
{% block content %}
<h2>Index</h2>
{% endblock %}

Would throw:

PHP Fatal error: Uncaught exception 'Phalcon\DI\Exception' with message 'Service 'view' wasn't found in the dependency injection container' in index.php:15
Stack trace:

0 [internal function]: Phalcon\DI->get('view')

1 [internal function]: Phalcon\Mvc\View\Engine\Volt\Compiler->_compileSource('{% extends "lay...')

2 [internal function]: Phalcon\Mvc\View\Engine\Volt\Compiler->compile('views/index/ind...', 'views/index/ind...')

3 [internal function]: Phalcon\Mvc\View\Engine\Volt->render('views/index/ind...', Array, true)

4 [internal function]: Phalcon\Mvc\View->_engineRender(Array, 'index/index', true, true, NULL)

5 /home/epatsiomkin/phalcon/index.php(15): Phalcon\Mvc\View->render('index', 'index')

6 {main} thrown in index.php on line 15

Though if you replace {% extends "layouts/main.html" %} with {% extends "views/layouts/main.html" %} in views/index/index.html Everything renders properly.

It also works if you add view to di $di->set('view', $view); with original templates but it does not feel right in this case. As I would expect view would register itself on setDi() call.

@niden
Copy link
Member

niden commented Dec 5, 2012

Yauheni,

Try registering Volt this way:

//Register Volt as a service
$di->set('volt', function($view, $di) {
return new \Phalcon\Mvc\View\Engine\Volt($view, $di);
});

//Register Volt as template engine

$di->set('view', function() {

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

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

$view->registerEngines(array(
    ".volt" => 'volt'
));

return $view;

});

You need to tell the DI container what service the view is using. In your implementation you are doing it right but not registering the view in the DI

@eugene-p
Copy link
Author

eugene-p commented Dec 5, 2012

I do know how to set code up to make it work. My concerns are more with architecture

I have 2 concerns in current situation:

  1. View depends on Engine, Engine depends on View. It looks like a circular dependency. And does not sound like a good idea.
  2. Even if first part is not an issue, view should act same no matter how extend paths are specified. But it only tries to access view only if path relative to view root is specified.

So as a solution I was suggesting to register view automatically on setDi in dependency container. Now when I think of it, better solution might be to pass view root folder on Phalcon\Mvc\View->_engineRender() call

@phalcon
Copy link
Collaborator

phalcon commented Dec 19, 2012

Hi eugene, this was changed in 0.8.0, to avoid the circular dependency, thanks

@phalcon phalcon closed this as completed Dec 19, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature request Planned Feature or New Feature Request
Projects
None yet
Development

No branches or pull requests

2 participants