当我使用视图组件时,Yii2如何用@ app / themes / basic / layouts / main.php替换@ app / views / layouts / main.php

时间:2017-08-29 01:26:59

标签: php yii2 yii2-advanced-app theming

如果我使用像文档那样的视图组件

    using (TextFieldParser csvParser = new TextFieldParser(path)) {
                    csvParser.CommentTokens = new string[] { "#" };
                    csvParser.SetDelimiters(new string[] { "," });
                    csvParser.HasFieldsEnclosedInQuotes = true;

                    csvParser.ReadLine();

int offsetX = 30;
int offsetY = 40;
int counter;

                    while (!csvParser.EndOfData) {
                    int pointerY = ++counter * offsetY; // first counter increments by one, then counter times offsetY occurs
                    int pointerX;

                        string[] fields = csvParser.ReadFields();
                        int rowNums = fields.Length;

                        for(int index = 0; index < rowNums;index++) {
pointerX = (index + 1) * offsetX;

                            string name = fields[index];
                            TextBox n = new TextBox() { Text = name, Location = new Point(pointerX, pointerY) };
                            panel2.Controls.Add(n);
                            panel2.Show(); // should be unnecessary
                        }
                    }
                }

是否意味着@ app / themes / basic / layouts / main.php文件夹中的main.php将替换@ app / views / layouts / main.php文件夹中的main.php?

以及yii2如何实现这一目标?虽然我跟踪控制器找到了一些可以帮助我理解逻辑的东西,但我无法弄明白。

我跟踪代码如下,但我没有找到在使用主题时如何替换布局main.php。

1.SiteController,默认动作索引,然后渲染视图

return [
    'components' => [
        'view' => [
            'theme' => [
                'basePath' => '@app/themes/basic',
                'baseUrl' => '@web/themes/basic',
                'pathMap' => [
                    '@app/views' => '@app/themes/basic',
                ],
            ],
        ],
    ],
];

2.调用Controller类函数render

public function actionIndex()
{
    return $this->render('index');
}

3.get yii \ web \ View

public function render($view, $params = [])
{
    $content = $this->getView()->render($view, $params, $this);
    return $this->renderContent($content);
}

4.使用View类函数渲染

public function getView()
{
    if ($this->_view === null) {
        $this->_view = Yii::$app->getView();
    }
    return $this->_view;
}

5.查看视图文件,获取视图文件路径

public function render($view, $params = [], $context = null)
{
    $viewFile = $this->findViewFile($view, $context);
    return $this->renderFile($viewFile, $params, $context);
}

6.渲染此视图文件

protected function findViewFile($view, $context = null)
{
    if (strncmp($view, '@', 1) === 0) {
        // e.g. "@app/views/main"
        $file = Yii::getAlias($view);
    } elseif (strncmp($view, '//', 2) === 0) {
        // e.g. "//layouts/main"
        $file = Yii::$app->getViewPath() . DIRECTORY_SEPARATOR . ltrim($view, '/');
    } elseif (strncmp($view, '/', 1) === 0) {
        // e.g. "/site/index"
        if (Yii::$app->controller !== null) {
            $file = Yii::$app->controller->module->getViewPath() . DIRECTORY_SEPARATOR . ltrim($view, '/');
        } else {
            throw new InvalidCallException("Unable to locate view file for view '$view': no active controller.");
        }
    } elseif ($context instanceof ViewContextInterface) {
        $file = $context->getViewPath() . DIRECTORY_SEPARATOR . $view;
    } elseif (($currentViewFile = $this->getViewFile()) !== false) {
        $file = dirname($currentViewFile) . DIRECTORY_SEPARATOR . $view;
    } else {
        throw new InvalidCallException("Unable to resolve view file for view '$view': no active view context.");
    }

    if (pathinfo($file, PATHINFO_EXTENSION) !== '') {
        return $file;
    }
    $path = $file . '.' . $this->defaultExtension;
    if ($this->defaultExtension !== 'php' && !is_file($path)) {
        $path = $file . '.php';
    }
    return $path;
}

7.如果主题不为null,系统将调用$ this-&gt; theme-&gt; applyTo($ viewFile)来获取主题视图文件,并使用renderPhpFile

public function renderFile($viewFile, $params = [], $context = null)
{
    $viewFile = Yii::getAlias($viewFile);
    if ($this->theme !== null) {
        $viewFile = $this->theme->applyTo($viewFile);
    }
    if (is_file($viewFile)) {
        $viewFile = FileHelper::localize($viewFile);
    } else {
        throw new ViewNotFoundException("The view file does not exist: $viewFile");
    }

    $oldContext = $this->context;
    if ($context !== null) {
        $this->context = $context;
    }
    $output = '';
    $this->_viewFiles[] = $viewFile;

    if ($this->beforeRender($viewFile, $params)) {
        Yii::trace("Rendering view file: $viewFile", __METHOD__);
        $ext = pathinfo($viewFile, PATHINFO_EXTENSION);
        if (isset($this->renderers[$ext])) {
            if (is_array($this->renderers[$ext]) || is_string($this->renderers[$ext])) {
                $this->renderers[$ext] = Yii::createObject($this->renderers[$ext]);
            }
            /* @var $renderer ViewRenderer */
            $renderer = $this->renderers[$ext];
            $output = $renderer->render($this, $viewFile, $params);
        } else {
            $output = $this->renderPhpFile($viewFile, $params);
        }
        $this->afterRender($viewFile, $params, $output);
    }

    array_pop($this->_viewFiles);
    $this->context = $oldContext;

    return $output;
}

8.确认此文件的内容

1 个答案:

答案 0 :(得分:0)

这是因为当Yii2在config / components中执行渲染检查时,视图容器的实际映射是直接的。

这可能与您案例中的所有观点相关

    'view' => [
        'theme' => [
            'basePath' => '@app/themes/basic',
            'baseUrl' => '@web/themes/basic',
            'pathMap' => [
                '@app/views' => '@app/themes/basic',
            ],
        ],
    ],

或者可以与某些供应商相关或模数为

'view' => [
     'theme' => [
        'pathMap' => [
           '@dektrium/user/views' => '@backend/views/my-view-user'  // mapping per overriding s dektrium  views with personal  views 
         ],
     ],
 ],

您可以查看观看http://www.yiiframework.com/doc-2.0/yii-base-view.html

的参考文档

https://github.com/yiisoft/yii2/blob/master/framework/base/View.php