跳转到内容

视图


概览

视图代表应用程序的用户界面。视图通常是包含嵌入式 PHP 代码的 HTML 文件,这些代码仅用于执行与数据展示相关的任务。视图会格式化你需要发送回发起请求的用户/网页浏览器的内容。

Phalcon\Mvc\ViewPhalcon\Mvc\View\Simple负责管理你 MVC 应用程序中的视图层。

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property View $view
 */
class InvoicesController extends Controller
{
    public function viewAction($invoiceId)
    {
        $this->view->invoiceId = $invoiceId;
    }
}

常量

有几个常量可以在视图中设置以控制渲染过程的行为

常量 描述
LEVEL_ACTION_VIEW 渲染层级:到动作视图
LEVEL_BEFORE_TEMPLATE 渲染层级:到“before”模板
LEVEL_LAYOUT 渲染层级:到控制器布局
LEVEL_MAIN_LAYOUT 渲染层级:到主布局
LEVEL_NO_RENDER 渲染层级:不渲染任何视图
LEVEL_AFTER_TEMPLATE 渲染层级:渲染到“after”模板

方法

public function __construct(array options = [])
Phalcon\Mvc\View 构造函数

public function __get(string $key): mixed | null
魔术方法,用于检索传递给视图的变量

echo $this->view->invoices;

public function __isset(string $key): bool
魔术方法,用于检查视图中是否设置了某个变量

echo isset($this->view->invoices);

public function __set(string $key, var value)
魔术方法,用于将变量传递给视图

$this->view->invoices = $invoices;

public function cleanTemplateAfter(): View
重置所有“before”模板布局

public function cleanTemplateBefore(): View
重置所有“before”模板布局

public function disableLevel(mixed $level): ViewInterface
禁用特定级别的渲染

$this->view->disableLevel(
    View::LEVEL_ACTION_VIEW
);
渲染除ACTION级别外的所有层级

public function disable(): View
禁用自动渲染进程

public function enable(): View
启用自动渲染进程

public function exists(string $view): bool
检查视图是否存在

public function finish(): View
通过停止输出缓冲结束渲染过程

public function getActionName(): string
获取已渲染动作的名称

public function getActiveRenderPath(): string | array
返回当前渲染视图的路径(或多个路径)

public function getBasePath(): string
获取基础路径

public function getContent(): string
返回另一个视图阶段的输出

public function getControllerName(): string
获取已渲染控制器的名称

public function getLayout(): string
返回主视图的名称

public function getLayoutsDir(): string
获取当前布局子目录

public function getMainView(): string
返回主视图的名称

public function getParamsToView(): array
返回传递给视图的参数

public function getPartial(
    string $partialPath, 
    mixed $params = null
): string
渲染一个局部视图

echo $this->getPartial("shared/footer");
检索一个局部视图的内容

echo $this->getPartial(
    "shared/footer",
    [
        "content" => $html,
    ]
);
使用参数检索一个局部视图的内容

public function getPartialsDir(): string
获取当前部分视图的子目录

public function getRender(
    string $controllerName, 
    string $actionName, 
    array $params = [], 
    mixed configCallback = null
): string
执行自动渲染并将输出作为字符串返回

$template = $this->view->getRender(
    "invoices",
    "show",
    [
        "invoices" => $invoices,
    ]
);

public function getVar(string $key)
返回之前在视图中设置的参数

public function getViewsDir(): string | array
获取视图目录

protected function getViewsDirs(): array
获取多个视图目录

public function isDisabled(): bool
是否启用了自动渲染

public function partial(
    string $partialPath, 
    mixed $params = null
)
渲染一个局部视图

$this->partial("shared/footer");
在另一个视图中显示一个局部视图

$this->partial(
    "shared/footer",
    [
        "content" => $html,
    ]
);
带参数在一个视图中显示一个局部视图

public function pick(var renderView): View
选择一个不同的视图进行渲染,而不是最后控制器/最后动作对应的视图

use Phalcon\Mvc\Controller;

class ProductsController extends Controller
{
    public function saveAction()
    {
        // ...

        $this->view->pick("invoices/list");
    }
}

public function registerEngines(
    array $engines
): View
注册模板引擎

$this->view->registerEngines(
    [
        ".phtml" => \Phalcon\Mvc\View\Engine\Php::class,
        ".volt"  => \Phalcon\Mvc\View\Engine\Volt::class,
        ".mhtml" => \MyCustomEngine::class,
    ]
);

public function render(
    string $controllerName,
    string $actionName,
    array $params = []
): View | bool
从分发的数据开始执行渲染过程

$view
    ->start()
    ->render("posts", "recent")
    ->finish()
;
显示最近文章视图 (app/views/posts/recent.phtml)

public function reset(): View
将视图组件重置为出厂默认值

public function setBasePath(
    string $basePath
): View
设置基础路径。根据你的平台不同,请始终添加末尾斜杠或反斜杠

$view->setBasePath(__DIR__ . "/");

public function setContent(
    string $content
): View
外部设置视图内容

$this->view->setContent(
    "<h1>hello</h1>"
);

public function setLayout(
    string $layout
): View
更改使用的布局,而不是使用最新控制器的名称

$this->view->setLayout("main");

public function setLayoutsDir(
    string $layoutsDir
): View
设置布局子目录。它必须是视图目录下的一个目录。根据你的平台不同,请始终添加末尾斜杠或反斜杠

$view->setLayoutsDir(
    "../common/layouts/"
);

public function setMainView(
    string viewPath
): View
设置默认视图名称。它必须是一个没有扩展名的文件,并且位于视图目录下

$this->view->setMainView("base");
渲染 views-dir/base.phtml 作为主视图

public function setPartialsDir(
    string $partialsDir
): View
设置部分视图子目录。它必须是视图目录下的一个目录。根据你的平台不同,请始终添加末尾斜杠或反斜杠

$view->setPartialsDir(
    "../common/partials/"
);

public function setParamToView(
    string $key, 
    mixed $value
): View
向视图添加参数(setVar 的别名)

$this
    ->view
    ->setParamToView("invoices", $invoices)
;

public function setRenderLevel(
    int $level
): ViewInterface
设置视图的渲染层级

$this->view->setRenderLevel(
    View::LEVEL_LAYOUT
);
仅渲染与控制器相关的视图

public function setTemplateAfter(
    mixed $templateAfter
): View
设置一个“after”模板控制器布局

public function setTemplateBefore(
    mixed $templateBefore
): View
在控制器布局前设置一个模板

public function setVar(
    string $key, 
    mixed $value
): View
设置单个视图参数

$this
    ->view
    ->setVar("invoices", $invoices)
;

public function setVars(
    array $params, 
    bool $merge = true
): View
设置所有渲染参数

$this->view->setVars(
    [
        "invoices" => $invoices,
    ]
);

public function setViewsDir(
    mixed $viewsDir
): View
设置视图目录。根据你的平台不同,请始终添加末尾斜杠或反斜杠

public function start(): View
开始渲染过程并启用输出缓冲

public function toString(
    string $controllerName,
    string $actionName,
    array params = []
): string
渲染视图并将其作为字符串返回

激活

必须在 DI 容器中注册视图组件才能在应用程序中启用视图功能。

<?php

use Phalcon\Di\FactoryDefault;
use Phalcon\Mvc\View;

$container = new FactoryDefault();

$container->set(
    'view',
    function () {
        $view = new View();

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

        return $view;
    }
);
如果未定义任何引擎,Phalcon\Mvc\View\Engine\Php将会自动为你注册。这些是包含 PHP 和 HTML 代码并且具有以下扩展名的文件:.phtml。有关Volt模板引擎的更多信息,请查阅相关文档。

控制器中的视图

一旦某个控制器完成其生命周期,Phalcon 会自动将执行权交给视图组件。视图组件将在 views 文件夹中查找名为最后一次执行控制器同名的文件夹,然后查找名为最后一次执行动作名称的文件。例如,如果请求发送到以下 URL:https://dev.phalcon.ld/admin/invoices/view/12345,Phalcon 将解析该 URL 如下:

服务器地址 127.0.0.1
Phalcon 目录 admin
控制器 invoices
动作 view
参数 12345

调度器将寻找一个InvoicesController及其动作viewAction。本例的一个简单控制器文件:

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property View $view
 */
class InvoicesController extends Controller
{
    public function viewAction($invoiceId)
    {
        $this->view->setVar('invoiceId', $invoiceId);
    }
}

The setVar()方法允许我们按需创建视图变量,以便它们可以在视图模板中使用。上面的例子演示了如何将$invoiceId参数传递给相应的视图模板。

分层渲染

Phalcon\Mvc\View是 Phalcon 中用于渲染视图的默认组件,并支持文件的层次结构。这种层次结构允许有通用的布局点(常用视图),以及以控制器命名的文件夹来定义各自的视图模板。

视图组件的默认渲染引擎是 PHP。因此,所有与视图相关的文件都需要具有.phtml扩展名。对于上面的例子:

https://dev.phalcon.ld/admin/invoices/view/12345
假设视图目录是app/views,视图组件会自动找到以下 3 个视图文件:

名称 文件 描述
动作视图 app/views/invoices/view.phtml 与动作相关的视图。只有当view动作执行时才会被渲染。
控制器布局 app/views/layouts/invoices.phtml 与控制器相关的视图。它将在InvoicesController.
主布局 app/views/index.phtml 应用程序相关视图。在应用程序的每个控制器/动作中都会显示

并非必须实现上述所有文件。Phalcon\Mvc\View只需简单地移至文件层级结构中的下一个视图层级即可。如果实现了全部三个视图文件,它们将按如下方式处理:

<!-- app/views/invoices/view.phtml -->

<h3>View Name: "view"</h3>

<p>I have received the parameter <?php echo $invoiceId; ?></p>
<!-- app/views/layouts/invoices.phtml -->

<h2>Controller view: "invoices"</h2>

<?php echo $this->getContent(); ?>
<!-- app/views/index.phtml -->
<html>
    <head>
        <title>Example</title>
    </head>
    <body>
        <h1>Main layout!</h1>

        <?php echo $this->getContent(); ?>

    </body>
</html>

注意

$this->getContent()的调用指示Phalcon\Mvc\View在层级结构中前一个视图执行后的内容应注入到哪里。

对于上面的例子,输出将是:

生成的 HTML 将是:

<html>
    <head>
        <title>Example</title>
    </head>
    <body>
        <h1>Main layout!</h1>

        <!-- app/views/layouts/invoices.phtml -->

        <h2>Controller view: "invoices"</h2>

        <!-- app/views/invoices/view.phtml -->

        <h3>View Name: "view"</h3>

        <p>I have received the parameter 12345</p>

    </body>
</html>

模板

模板是可以用来共享通用视图代码的视图。它们的作用类似于控制器布局,因此需要将它们放置在layouts目录下。

模板可以在布局之前(使用$this->view->setTemplateBefore())渲染,也可以在布局之后(使用this->view->setTemplateAfter())渲染。在下面的例子中,模板(layouts/common.phtml)在主布局(layouts/posts.phtml):

<?php

use Phalcon\Flash\Direct;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property Direct $flash
 * @property View   $view
 */
class InvoicesController extends Controller
{
    public function initialize()
    {
        $this->view->setTemplateAfter('common');
    }

    public function lastAction()
    {
        $this->flash->notice(
            'These are the latest invoices'
        );
    }
}
<!-- app/views/index.phtml -->
<!DOCTYPE html>
<html>
    <head>
        <title>Invoices</title>
    </head>
    <body>
        <?php echo $this->getContent(); ?>
    </body>
</html>
<!-- app/views/layouts/common.phtml -->

<ul class='menu'>
    <li><a href='/'>Home</a></li>
    <li><a href='/list'>List</a></li>
    <li><a href='/support'>Support</a></li>
</ul>

<div class='content'>
    <?php echo $this->getContent(); ?>
</div>
<!-- app/views/layouts/invoices.phtml -->

<h1>Invoices</h1>

<?php echo $this->getContent(); ?>
<!-- app/views/invoices/last.phtml -->

<article>
    <h2>This is a title</h2>
    <p>This is Invoice One</p>
</article>

<article>
    <h2>Another title</h2>
    <p>This is Invoice Two</p>
</article>

之后渲染。

<!-- app/views/index.phtml -->
<!DOCTYPE html>
<html>
    <head>
        <title>Invoices</title>
    </head>
    <body>

        <!-- app/views/layouts/common.phtml -->

        <ul class='menu'>
            <li><a href='/'>Home</a></li>
            <li><a href='/list'>List</a></li>
            <li><a href='/support'>Support</a></li>
        </ul>

        <div class='content'>

            <!-- app/views/layouts/invoices.phtml -->

            <h1>Invoices</h1>

            <!-- app/views/invoices/last.phtml -->

            <article>
                <h2>This is a title</h2>
                <p>This is Invoice One</p>
            </article>

            <article>
                <h2>Another title</h2>
                <p>This is Invoice Two</p>
            </article>

        </div>

    </body>
</html>

如果我们使用了$this->view->setTemplateBefore('common'),最终的输出将是:

<!-- app/views/index.phtml -->
<!DOCTYPE html>
<html>
    <head>
        <title>Blog's title</title>
    </head>
    <body>

        <!-- app/views/layouts/invoices.phtml -->

        <h1>Blog Title</h1>

        <!-- app/views/layouts/common.phtml -->

        <ul class='menu'>
            <li><a href='/'>Home</a></li>
            <li><a href='/articles'>Articles</a></li>
            <li><a href='/contact'>Contact us</a></li>
        </ul>

        <div class='content'>

            <!-- app/views/invoices/last.phtml -->

            <article>
                <h2>This is a title</h2>
                <p>This is the post content</p>
            </article>

            <article>
                <h2>This is another title</h2>
                <p>This is another post content</p>
            </article>

        </div>

    </body>
</html>

渲染层级

如上所示,Phalcon\Mvc\View支持视图层级结构。你可能需要控制视图组件产生的渲染层级。方法Phalcon\Mvc\View::setRenderLevel()提供此功能。

此方法可以从控制器或更高一级的视图层调用以干预渲染过程。

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property View   $view
 */
class InvoicesController extends Controller
{
    public function findAction()
    {
        $this->view->setRenderLevel(
            View::LEVEL_NO_RENDER
        );

        // ...
    }

    public function viewAction($invoiceId)
    {
        $this->view->setRenderLevel(
            View::LEVEL_ACTION_VIEW
        );
    }
}

可用的渲染层级包括:

类常量 描述 顺序
LEVEL_NO_RENDER 表示避免生成任何类型的呈现内容。
LEVEL_ACTION_VIEW 生成与动作关联的视图的呈现内容。 1
LEVEL_BEFORE_TEMPLATE 在控制器布局之前生成模板的呈现内容。 2
LEVEL_LAYOUT 生成控制器布局的呈现内容。 3
LEVEL_AFTER_TEMPLATE 在控制器布局之后生成模板的呈现内容。 4
LEVEL_MAIN_LAYOUT 生成主布局的呈现内容。文件 views/index.phtml 5

禁用渲染层级

你可以永久或临时禁用渲染层级。如果整个应用程序中完全不使用某一层级,则可以将其永久禁用:

<?php

use Phalcon\Mvc\View;

$container->set(
    'view',
    function () {
        $view = new View();

        // Disable several levels
        $view->disableLevel(
            [
                View::LEVEL_LAYOUT      => true,
                View::LEVEL_MAIN_LAYOUT => true,
            ]
        );

        return $view;
    },
    true
);

或者在应用程序的某些部分暂时禁用:

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property View   $view
 */
class InvoicesController extends Controller
{
    public function findAction()
    {
        $this->view->disableLevel(
            View::LEVEL_MAIN_LAYOUT
        );
    }
}

禁用视图

如果你的控制器不对视图产生任何输出(或者甚至没有视图),你可以禁用视图组件以避免不必要的处理:

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property View   $view
 */
class InvoicesController extends Controller
{
    public function processAction()
    {
        $this->view->disable();
    }
}

或者,你可以返回false来达到相同的效果:

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property View   $view
 */
class InvoicesController extends Controller
{
    public function processAction()
    {
        return false;
    }
}

你可以返回一个response对象来避免手动禁用视图:

<?php

use Phalcon\Http\Response;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property Response $response
 * @property View     $view
 */
class InvoicesController extends Controller
{
    public function processAction()
    {
        return $this
            ->response
            ->redirect('index/index')
        ;
    }
}

简单渲染

注意

你可以使用echo当调用$view->render()时,会将渲染过程的内容输出到屏幕上。这个功能仅适用于的文件Phalcon\Mvc\View\Simple的文件Phalcon\Mvc\View。在后者中使用它会产生警告。echo with the latter will produce a warning.

Phalcon\Mvc\View\SimplePhalcon\Mvc\View的替代组件。Phalcon\Mvc\View它保留了其大部分理念,实际上缺少文件层级结构,这是其对应组件的主要特性。

此组件允许你控制视图何时渲染及其位置。此外,该组件可以利用模板引擎(例如Volt和其他引擎)中可用的视图继承功能。

默认组件必须在服务容器中替换:

<?php

use Phalcon\Mvc\View\Simple;

$container->set(
    'view',
    function () {
        $view = new Simple();

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

        return $view;
    },
    true
);

自动渲染必须在Phalcon\Mvc\Application中禁用(如需要):

<?php

use Phalcon\Di\FactoryDefault;;
use Phalcon\Mvc\Application;

try {
    $container   = new FactoryDefault();
    $application = new Application($container);

    $application->useImplicitView(false);

    $response = $application->handle(
        $_SERVER["REQUEST_URI"]
    );

    $response->send();
} catch (Exception $e) {
    echo $e->getMessage();
}

要渲染视图,必须显式调用 render 方法,并指定要显示的视图的相对路径:

<?php

use Phalcon\Http\Response;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property Response $response
 * @property View     $view
 */
class InvoicesController extends Controller
{

    public function indexAction()
    {
        // 'views-dir/index.phtml'
        echo $this->view->render('index');

        // 'views-dir/posts/show.phtml'
        echo $this->view->render('posts/show');

        // 'views-dir/index.phtml' passing variables
        echo $this->view->render(
            'index',
            [
                'posts' => Invoices::find(),
            ]
        );

        // 'views-dir/invoices/view.phtml' passing variables
        echo $this->view->render(
            'invoices/view',
            [
                'posts' => Invoices::find(),
            ]
        );
    }
}

这与renderPhalcon\Mvc\View实现的方式不同,后者使用控制器和动作为参数:

<?php

use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Simple;

$params = [
    'invoices' => Invoices::find(),
];

// Phalcon\Mvc\View
$view = new View();
$view->render('invoices', 'view', $params);

// Phalcon\Mvc\View\Simple
$simpleView = new Simple();
echo $simpleView->render('invoices/view', $params);

选择视图

如上所述,当Phalcon\Mvc\ViewPhalcon\Mvc\Application管理时,所渲染的视图是最后执行的控制器和动作相关联的视图。你可以通过使用pick()方法:

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property Response $response
 * @property View     $view
 */
class InvoicesController extends Controller
{
    public function listAction()
    {
        // Pick 'views-dir/invoices/search' as a view to render
        $this->view->pick('invoices/search');

        // Pick 'views-dir/invoices/list' as a view to render
        $this->view->pick(
            [
                'invoices',
            ]
        );

        // Pick 'views-dir/invoices/search' as a view to render
        $this->view->pick(
            [
                1 => 'search',
            ]
        );
    }
}

局部视图

局部模板是另一种将渲染过程拆分为更简单且易于管理的块的方法,这些块可以在应用程序的不同部分重用。使用局部视图,你可以将用于渲染响应特定部分的代码移动到自己的文件中。

使用局部视图的一种方法是将其视为 HTML 片段,可以通过任何必要的参数将其注入到所需的位置:

<div class='top'>
    <?php $this->partial('shared/ad_banner'); ?>
</div>

<div class='content'>
    <h1>Invoices</h1>

    <p>Check out our specials!</p>
    ...
</div>

<div class='footer'>
    <?php $this->partial('shared/footer'); ?>
</div>

The partial()方法确实接受第二个参数,这是一个数组变量/参数,只会在局部视图的作用域内存在:

<?php 
    $this->partial(
        'shared/ad_banner', 
        [
            'id'   => $site->id, 
            'size' => 'big'
        ]
    ); 
?>

变量

Phalcon\Mvc\View在每个控制器中可通过视图变量($this->view)访问。你可以通过使用setVar()方法设置容器。

<?php

use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;

/**
 * @property View $view
 */
class InvoicesController extends Controller
{
    public function viewAction($invoiceId)
    {
        $invoice = Invoices::findFirst(
            [
                'conditions' => 'inv_id = :id:',
                'bind'       => [
                    'id' => abs(intval($invoiceId)),
                ]
            ]
        );
        $customer = $invoice->getRelated('customer');

        $this->view->setVar('invoice', $invoice);

        $this->view->customerId = $customer->cst_id;

        $this->view->setVars(
            [
                'name_first' => $customer->name_first,
                'name_last'  => $customer->name_last,
            ]
        );
    }
}

方法从控制器动作中直接向视图设置变量:setVar()的第一个参数名称的变量将在视图中创建,准备好供使用。变量可以是任何类型,从简单的string, integer等变量到更复杂的结构如array、集合等。

<h1>
    Invoices [Customer #{{ customerId }}]
</h1>

<div class='invoice'>
<?php

    foreach ($invoices as $invoice) {
        echo '<h2>', $invoice->inv_title, '</h2>';
    }

?>
</div>

模板引擎

模板引擎帮助设计人员创建视图,而无需使用复杂的语法。Phalcon 包含一个强大快速的模板引擎叫做Volt,它有助于视图开发同时不会牺牲处理速度。

PHP

The Phalcon\Mvc\View\Engine\Php是默认的模板引擎,如果没有指定的话。

<?php

use Phalcon\Mvc\View;

$container->set(
    'view',
    function () {
        $view = new View();

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

        return $view;
    },
    true
);

Volt

您可能会想要使用Volt作为您的模板引擎。要进行设置,您需要注册该引擎并将其传递给视图组件。

<?php

use Phalcon\Di\FactoryDefault;
use Phalcon\Di\DiInterface;
use Phalcon\Mvc\ViewBaseInterface;
use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Volt;

$container = new FactoryDefault();

$container->setShared(
    'voltService',
    function (ViewBaseInterface $view) {
        $volt = new Volt($view, $this);
        $volt->setOptions(
            [
                'always'    => true,
                'extension' => '.php',
                'separator' => '_',
                'stat'      => true,
                'path'      => appPath('storage/cache/volt/'),
                'prefix'    => '-prefix-',
            ]
        );

        return $volt;
    }
);

$container->set(
    'view',
    function () {
        $view = new View();

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

        $view->registerEngines(
            [
                '.volt' => 'voltService',
            ]
        );

        return $view;
    }
);

Mustache/Twig/Smarty

如果您希望使用Mustache, TwigSmarty作为您的模板引擎,您可以访问我们的孵化器仓库,获取如何在应用程序中激活这些引擎的示例

自定义

使用外部模板引擎时,Phalcon\Mvc\View提供完全相同的视图层次结构,并且仍然可以在这些模板中访问API。如果您想创建自己的模板引擎,可以利用该API执行所需的任何操作。

一个模板引擎适配器是一个类,它充当Phalcon\Mvc\View和模板引擎本身的桥梁。通常,它只需要实现两个方法:__construct()render()。第一个方法接收Phalcon\Mvc\View创建引擎适配器的实例和应用程序使用的DI容器。

方法render()接收一个指向视图文件的绝对路径以及通过$this->view->setVar()设置的视图参数。在必要时,您可以选择读取或引入该文件。

<?php

use Phalcon\Di\DiInterface;
use Phalcon\Mvc\View\Engine\AbstractEngine;
use Phalcon\Mvc\View;

class CustomEngine extends AbstractEngine
{
    /**
     * @param View        $view
     * @param DiInterface $container
     */
    public function __construct($view, DiInterface $container)
    {
        parent::__construct($view, $container);
    }

    /**
     * @param string $path
     * @param array $params
     */
    public function render(string $path, $params)
    {
        // Access view
        $view = $this->view;

        // Options
        $options = $this->options;

        // Render the view
        // ...
    }
}

您现在可以在代码的视图设置部分将自己的模板引擎替换进去。您可以同时使用多个引擎。要做到这一点,您需要调用Phalcon\Mvc\View::registerEngines()它接受一个包含哪些引擎需要被注册的设置指令数组。每个引擎的键是需要处理的文件的扩展名。您不能注册两个具有相同键的引擎。

使用Phalcon\Mvc\View::registerEngines()定义模板引擎的顺序Phalcon\Mvc\View找到两个同名但扩展名不同的视图时,它只会渲染第一个。

<?php

use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Php;

$container->set(
    'view',
    function () {
        $view = new View();

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

        $view->registerEngines(
            [
                '.my-html' => \CustomEngine::class,
            ]
        );

        $view->registerEngines(
            [
                '.my-html' => \CustomEngine::class,
                '.phtml'   => Php::class,
            ]
        );

        return $view;
    },
    true
);

依赖注入

由于我们的视图是在依赖注入容器中注册的,所以在容器中可用的服务在视图中同样可用。每个服务都可以通过与定义的服务同名的属性访问。

<script type='text/javascript'>

$.ajax({
    url: '<?php echo $this->url->get('invoices/get'); ?>'
})
.done(function () {
    alert('Done!');
});

</script>

在上面的例子中,我们在JavaScript代码中使用了Phalcon\Mvc\Url组件,以正确地在应用程序中设置URL。通过访问$this->url.

独立模式

您也可以将视图用作应用程序中的胶水组件。您只需进行适当的配置,然后使用视图返回处理结果。

分层渲染

当您为视图设置了应用程序所需的选项后,您可以像上面提到的一样向其传递变量,然后调用start(), render()finish()。这将允许视图编译数据并为您做好准备。可以通过调用getContent().

<?php

use Phalcon\Mvc\View;

$view = new View();

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

//...

$view->setVar('invoices', $invoices);
$view->setVar('isAdmin', true);

$view->start();
$view->render('invoices', 'list');
$view->finish();

echo $view->getContent();

或使用更简短的语法来打印内容:

<?php

use Phalcon\Mvc\View;

$view = new View();

echo $view->getRender(
    'invoices',
    'list',
    [
        'invoices' => $invoices,
        'isAdmin'  => true,
    ],
    function ($view) {
        $view->setViewsDir('../app/views/');

        $view->setRenderLevel(
            View::LEVEL_LAYOUT
        );
    }
);

简单渲染

注意

你可以使用echo当调用$view->render()时,会将渲染过程的内容输出到屏幕上。这个功能仅适用于的文件Phalcon\Mvc\View\Simple的文件Phalcon\Mvc\View。在后者中使用它会产生警告。echo with the latter will produce a warning.

您还可以使用更加轻量级的Phalcon\Mvc\View\Simple作为一个独立组件。当您想要渲染一个不总是绑定到应用程序结构的模板时,该组件非常有用。例如,渲染电子邮件所需的HTML代码。

<?php

use Phalcon\Mvc\View\Simple;

$view = new Simple();

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

echo $view->render('templates/welcome');

echo $view->render(
    'templates/welcome',
    [
        'email'   => $email,
        'content' => $content,
    ]
);
在上面的例子中,我们设置了引擎,然后将一个渲染后的模板输出到屏幕(templates/welcome)。我们还可以通过传递一个数组作为第二个参数向模板发送参数。其键即为变量名。

事件

Phalcon\Mvc\ViewPhalcon\Mvc\View\Simple可以将事件发送给事件管理器如果其存在的话。事件使用类型view事件管理器false it can stop the active operation. The following events are supported:

事件名称 触发时机 可以停止
afterRender 渲染过程完成后
afterRenderView 渲染现有视图后
beforeRender 开始渲染过程之前
beforeRenderView 渲染现有视图之前
notFoundView 当找不到视图时

下面的示例演示了如何将监听器附加到此组件上:

<?php

use Phalcon\Di\FactoryDefault;
use Phalcon\Events\Event;
use Phalcon\Events\Manager;
use Phalcon\Mvc\View;

$container = new FactoryDefault();
$container->set(
    'view',
    function () {
        $manager = new Manager();

        $manager->attach(
            'view',
            function (Event $event, $view) {
                echo $event->getType(), ' - ', 
                     $view->getActiveRenderPath(), PHP_EOL;
            }
        );

        $view = new View();

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

        $view->setEventsManager($manager);

        return $view;
    },
    true
);

下面的例子展示如何创建一个插件,整理渲染过程中生成的HTML,使用的是Tidy.

<?php

use Phalcon\Events\Event;

class TidyPlugin
{
    public function afterRender(Event $event, $view)
    {
        $tidyConfig = [
            'clean'          => true,
            'output-xhtml'   => true,
            'show-body-only' => true,
            'wrap'           => 0,
        ];

        $tidy = tidy_parse_string(
            $view->getContent(),
            $tidyConfig,
            'UTF8'
        );

        $tidy->cleanRepair();

        $view->setContent(
            (string) $tidy
        );
    }
}
现在我们可以将其附加到我们的事件管理器上:

<?php

$manager->attach(
    'view:afterRender',
    new TidyPlugin()
);

异常

在视图组件中抛出的任何异常(Phalcon\Mvc\ViewPhalcon\Mvc\View\Simple)都将属于Phalcon\Mvc\ExceptionPhalcon\View\Engine\Volt\Exception如果您正在使用Volt。你可以使用此异常选择性地捕获仅从此组件抛出的异常。

<?php

use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Exception;

try {

    $view = new View();

    echo $view->getRender(
        'unknown-view',
        'list',
        [
            'invoices' => $invoices,
            'isAdmin'  => true,
        ],
        function ($view) {
            $view->setViewsDir('../app/views/');

            $view->setRenderLevel(
                View::LEVEL_LAYOUT
            );
        }
    );
} catch (Exception $ex) {
    echo $ex->getMessage();
}
无噪 Logo
无噪文档
25 年 6 月翻译
版本号 5.9
文档源↗