【问题标题】:Is it possible to render custom view (just custom .phtml) template with Phalcon\Mvc\View?是否可以使用 Phalcon\Mvc\View 呈现自定义视图(只是自定义 .phtml)模板?
【发布时间】:2013-01-14 22:02:21
【问题描述】:

我需要在变量中呈现电子邮件模板以便稍后发送它们(存储在 .phtml 文件中),我真的不想实现我的特殊类来处理这个。

是否可以不渲染控制器动作视图,而是自定义一个?

我尝试了以下代码,但它输出 NULL :((

// Controller context
$view = new Phalcon\Mvc\View();
$view->setViewsDir('app/views/');
$view->setVar('var1', 'var2');
// Setting some vars...
$view->start();
$view->partial($emailTemplatePath);
$view->finish();
$result = $view->getContent();
var_dump($result); // Gives null

【问题讨论】:

    标签: phalcon


    【解决方案1】:

    除了 Nikolaos 的响应之外,您还可以使用 $view->getRender() 来渲染返回其输出的单个视图。

    $view->setViewsDir('apps/views/');
    echo $view->getRender('partials', 'test'); // get apps/views/partials/test.phtml
    

    【讨论】:

    • 这适用于仅渲染文件,即某些控制器操作的视图。就我而言,我有不同的文件夹和不同的电子邮件模板。
    • 将第一个参数看成是views目录下的子目录:echo $view->getRender('templates/email', 'some'); // 获取应用程序/视图/模板/电子邮件/some.phtml
    • 当我这样做时,我的整个网站模板 (index.phtml) 也会附加到我的内容中。知道为什么吗?
    【解决方案2】:

    您需要检查$emailTemplatePath 的路径。它应该指向正确的文件,即

    // points to app/views/partials/email.phtml
    $view->partial('partials/email');
    

    如果您使用 Volt 并已将其注册为您的引擎,那么您的文件将需要:

    // app/views/partials/email.volt
    

    【讨论】:

    • 我尝试在我的示例中做同样的事情(有问题),但 $view->getContent() 返回 null.. :((
    • 如果你使用Volt,别忘了通过registerEngines()方法定义模板引擎。
    【解决方案3】:

    我有一个项目,我使用电子邮件和 pdf 模板,我所做的就是让渲染全部发生在组件内。

    首先,我的文件夹结构包含(我只会放在这里相关的)缓存、组件和视图目录。让我们看看电子邮件设置而不是 PDF,因为这与您的情况更相关。

    /app
        /cache
            /email
        /components
        /views
            /email
                /elements
    

    当然有公共、控制器等,但我们不要为此考虑它们。

    我正在使用 Swift 邮件程序,但我希望你也能使用它。在 /app/components/Swift.php 我有一个 __construct 调用 this->init_template_engine();

    /**
     * Create a volt templating engine for generating html
     */
    private function init_template_engine() {
        $this->_template = new \Phalcon\Mvc\View\Simple();
        $di = new \Phalcon\DI\FactoryDefault(); 
        $this->_template->setDI($di);
        $this->_template->registerEngines([
          '.volt' => function($view, $di) {
    
                $volt = new \Phalcon\Mvc\View\Engine\Volt($view, $di);
    
                $volt->setOptions([
                    'compiledPath' => APP_DIR."cache".DS."email".DS,  // render cache in /app/cache/email/
                    'compiledSeparator' => '_'
                ]);
    
                return $volt;
    
          // or use ".phtml" => 'Phalcon\Mvc\View\Engine\Php' if you want, 
          // both will accept PHP code if ya don't fancy it being a 100% volt.
            },
        ]);
    
        // tell it where your templates are
        $this->_template->setViewsDir(APP_DIR.'views'.DS.'email'.DS); 
    
        return $this->_template;
    }
    

    上面的常量(如 APP_DIR)是我已经在我的引导程序中创建的,它们所做的只是存储目录的完整路径。

    一旦 $_template 变量设置了模板引擎,我就可以使用它来呈现我的模板。

    /**
     * Returns HTML via Phalcon's volt engine.
     * @param  string $template_name
     * @param  array $data
     */
    private function render_template($template_name = null, $data = null) {
        // Check we have some data.
        if (empty($data)) {
            return false; // or set some default data maybe?
        }
    
        // Use the template name given to render the file in views/email
        if(is_object($this->_template) && !empty($template_name)) {
            return $this->_template->render($template_name, ['data' => $data]);
        }
    
        return false;
    }
    

    一个示例伏特电子邮件模板可能如下所示:

    {{ partial('elements/email_head') }}
    
    <h2>Your Order has been dispatched</h2>
    
    <p>Dear {{ data.name }}</p>
    
    <p>Your order with ACME has now been dispatched and should be with you within a few days.</p>
    
    <p>Do not hesitate to contact us should you have any questions when your waste of money arrives.</p>
    <p>Thank you for choosing ACME Inc.</p>
    
    {{ partial('elements/email_foot') }}
    

    我所要做的就是获取 html 并使用 swiftmailer 的 setBody 方法,我就完成了:

    ->setBody($this->render_template($template, $data), 'text/html');

    您不需要像这样在组件中放置单独的视图引擎,它可能会像那样占用大量内存,但它确实显示了整个过程。希望这是有道理的:)

    【讨论】:

      【解决方案4】:

      渲染视图并将其作为变量返回的最简单方法是使用 Phalcon\Mvc\View\Simple 类。在您的控制器中,声明一个 Simple 视图类的新实例并将一个渲染引擎附加到它。然后你可以使用它的 render() 方法来选择一个视图文件并传入变量:

      // create a simple view to help render sections of the page
      $simple_view = new \Phalcon\Mvc\View\Simple();
      $simple_view->setViewsDir( __DIR__ . '/../views/' );
      $simple_view->setDI( $this->di );
      $simple_view->registerEngines(array(
          '.volt' => 'Phalcon\Mvc\View\Engine\Volt'
      ));
      
      // use the simple view to generate one or more widgets
      $widget_html = array();
      $widget_objects = $widget_search->getWidgetObjects();
      forEach( $widget_objects as $widget ){
          $widget_html[] = $simple_view->render('index/widgetview',array('widget'=>$widget));
      }
      
      // pass the html snippets as a variable into your regular view
      $this->view->setVar('widget_html',$widget_html);
      

      【讨论】:

        【解决方案5】:

        使用$view-&gt;render('partials/email') 而不是调用部分方法。

        【讨论】:

        • 这是最简单的答案,只是控制器中缺少return false;。如果没有return false;,它会呈现当前的动作视图文件。
        【解决方案6】:

        我通常使用 Volt 引擎,一个简单的方法是在 DI 容器中重新定义视图,如下所示:

        $view = $this->view;
        
        $content = $view->getRender('mail', 'show',
          array(
            "var1" => "some value 1",
            "var2" => "some value 2"
          ),
          function($view) {
              $view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_LAYOUT);
          }
        );
        
        echo $content;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-14
          • 1970-01-01
          • 2023-04-01
          • 2021-04-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多