mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-06 14:19:23 +08:00
Fixes #2912: Relative view files will be looked for under the directory containing the view currently being rendered
This commit is contained in:
@ -372,6 +372,20 @@ echo $this->render('_profile', [
|
||||
]);
|
||||
```
|
||||
|
||||
|
||||
When you call `render()` to render a partial in a current view, you may use different formats to refer to the partial.
|
||||
The most commonly used format is the so-called relative view name which is as shown in the above example.
|
||||
The partial view file is relative to the directory containing the current view. If the partial is located under
|
||||
a subdirectory, you should include the subdirectory name in the view name, e.g., `public/_profile`.
|
||||
|
||||
You may use path alias to specify a view, too. For example, `@app/views/common/_profile`.
|
||||
|
||||
And you may also use the so-called absolute view names, e.g., `/user/_profile`, `//user/_profile`.
|
||||
An absolute view name starts with a single slashes or double slashes. If it starts with a single slash,
|
||||
the view file will be looked for under the view path of the currently active module. Otherwise, it will
|
||||
will be looked for under the application view path.
|
||||
|
||||
|
||||
### Accessing context
|
||||
|
||||
Views are generally used either by controller or by widget. In both cases the object that called view rendering is
|
||||
|
@ -268,13 +268,11 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the view file corresponding to the specified relative view name.
|
||||
* @param string $view a relative view name. The name does NOT start with a slash.
|
||||
* @return string the view file path. Note that the file may not exist.
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function findViewFile($view)
|
||||
public function getViewPath()
|
||||
{
|
||||
return Yii::getAlias('@yii/apidoc/templates/html/views/' . $view);
|
||||
return Yii::getAlias('@yii/apidoc/templates/html/views');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,7 @@ $extensions = $panel->getExtensions();
|
||||
<h1>Configuration</h1>
|
||||
|
||||
<?php
|
||||
echo $this->render('panels/config/table', [
|
||||
echo $this->render('table', [
|
||||
'caption' => 'Application Configuration',
|
||||
'values' => [
|
||||
'Yii Version' => $panel->data['application']['yii'],
|
||||
@ -18,13 +18,13 @@ echo $this->render('panels/config/table', [
|
||||
]);
|
||||
|
||||
if (!empty($extensions)) {
|
||||
echo $this->render('panels/config/table', [
|
||||
echo $this->render('table', [
|
||||
'caption' => 'Installed Extensions',
|
||||
'values' => $extensions,
|
||||
]);
|
||||
}
|
||||
|
||||
echo $this->render('panels/config/table', [
|
||||
echo $this->render('table', [
|
||||
'caption' => 'PHP Configuration',
|
||||
'values' => [
|
||||
'PHP Version' => $panel->data['php']['version'],
|
||||
|
@ -11,27 +11,27 @@ echo Tabs::widget([
|
||||
'items' => [
|
||||
[
|
||||
'label' => 'Parameters',
|
||||
'content' => $this->render('panels/request/table', ['caption' => 'Routing', 'values' => ['Route' => $panel->data['route'], 'Action' => $panel->data['action'], 'Parameters' => $panel->data['actionParams']]])
|
||||
. $this->render('panels/request/table', ['caption' => '$_GET', 'values' => $panel->data['GET']])
|
||||
. $this->render('panels/request/table', ['caption' => '$_POST', 'values' => $panel->data['POST']])
|
||||
. $this->render('panels/request/table', ['caption' => '$_FILES', 'values' => $panel->data['FILES']])
|
||||
. $this->render('panels/request/table', ['caption' => '$_COOKIE', 'values' => $panel->data['COOKIE']])
|
||||
. $this->render('panels/request/table', ['caption' => 'Request Body', 'values' => $panel->data['requestBody']]),
|
||||
'content' => $this->render('table', ['caption' => 'Routing', 'values' => ['Route' => $panel->data['route'], 'Action' => $panel->data['action'], 'Parameters' => $panel->data['actionParams']]])
|
||||
. $this->render('table', ['caption' => '$_GET', 'values' => $panel->data['GET']])
|
||||
. $this->render('table', ['caption' => '$_POST', 'values' => $panel->data['POST']])
|
||||
. $this->render('table', ['caption' => '$_FILES', 'values' => $panel->data['FILES']])
|
||||
. $this->render('table', ['caption' => '$_COOKIE', 'values' => $panel->data['COOKIE']])
|
||||
. $this->render('table', ['caption' => 'Request Body', 'values' => $panel->data['requestBody']]),
|
||||
'active' => true,
|
||||
],
|
||||
[
|
||||
'label' => 'Headers',
|
||||
'content' => $this->render('panels/request/table', ['caption' => 'Request Headers', 'values' => $panel->data['requestHeaders']])
|
||||
. $this->render('panels/request/table', ['caption' => 'Response Headers', 'values' => $panel->data['responseHeaders']])
|
||||
'content' => $this->render('table', ['caption' => 'Request Headers', 'values' => $panel->data['requestHeaders']])
|
||||
. $this->render('table', ['caption' => 'Response Headers', 'values' => $panel->data['responseHeaders']])
|
||||
],
|
||||
[
|
||||
'label' => 'Session',
|
||||
'content' => $this->render('panels/request/table', ['caption' => '$_SESSION', 'values' => $panel->data['SESSION']])
|
||||
. $this->render('panels/request/table', ['caption' => 'Flashes', 'values' => $panel->data['flashes']])
|
||||
'content' => $this->render('table', ['caption' => '$_SESSION', 'values' => $panel->data['SESSION']])
|
||||
. $this->render('table', ['caption' => 'Flashes', 'values' => $panel->data['flashes']])
|
||||
],
|
||||
[
|
||||
'label' => '$_SERVER',
|
||||
'content' => $this->render('panels/request/table', ['caption' => '$_SERVER', 'values' => $panel->data['SERVER']]),
|
||||
'content' => $this->render('table', ['caption' => '$_SERVER', 'values' => $panel->data['SERVER']]),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
@ -228,6 +228,7 @@ Yii Framework 2 Change Log
|
||||
- Removed `yii\web\Controller::getCanonicalUrl`, use `yii\helpers\Url::canonical` instead.
|
||||
- Chg #2691: Null parameters will not be included in the generated URLs by `UrlManager` (gonimar, qiangxue)
|
||||
- Chg #2734: `FileCache::keyPrefix` defaults to empty string now (qiangxue)
|
||||
_ Chg #2912: Relative view files will be looked for under the directory containing the view currently being rendered (qiangxue)
|
||||
- Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue)
|
||||
- Chg: Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()` (qiangxue)
|
||||
- Chg: Renamed `attributeName` and `className` to `targetAttribute` and `targetClass` for `UniqueValidator` and `ExistValidator` (qiangxue)
|
||||
|
@ -289,7 +289,7 @@ class Controller extends Component implements ViewContextInterface
|
||||
*
|
||||
* If the layout name does not contain a file extension, it will use the default one `.php`.
|
||||
*
|
||||
* @param string $view the view name. Please refer to [[findViewFile()]] on how to specify a view name.
|
||||
* @param string $view the view name.
|
||||
* @param array $params the parameters (name-value pairs) that should be made available in the view.
|
||||
* These parameters will not be available in the layout.
|
||||
* @return string the rendering result.
|
||||
@ -367,17 +367,6 @@ class Controller extends Component implements ViewContextInterface
|
||||
return $this->module->getViewPath() . DIRECTORY_SEPARATOR . $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the view file based on the given view name.
|
||||
* @param string $view the view name or the path alias of the view file. Please refer to [[render()]]
|
||||
* on how to specify this parameter.
|
||||
* @return string the view file path. Note that the file may not exist.
|
||||
*/
|
||||
public function findViewFile($view)
|
||||
{
|
||||
return $this->getViewPath() . DIRECTORY_SEPARATOR . $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the applicable layout file.
|
||||
* @param View $view the view object to render the layout file.
|
||||
|
@ -98,7 +98,7 @@ class View extends Component
|
||||
|
||||
/**
|
||||
* @var array the view files currently being rendered. There may be multiple view files being
|
||||
* rendered at a moment because one may render a view file within another.
|
||||
* rendered at a moment because one view may be rendered within another.
|
||||
*/
|
||||
private $_viewFiles = [];
|
||||
|
||||
@ -127,13 +127,17 @@ class View extends Component
|
||||
* The actual view file will be looked for under the [[Application::viewPath|view path]] of the application.
|
||||
* - absolute path within current module (e.g. "/site/index"): the view name starts with a single slash.
|
||||
* The actual view file will be looked for under the [[Module::viewPath|view path]] of [[module]].
|
||||
* - resolving any other format will be performed via [[ViewContext::findViewFile()]].
|
||||
* - relative view (e.g. "index"): the view name does not start with `@` or `/`. The corresponding view file will be
|
||||
* looked for under the [[ViewContextInterface::getViewPath()|view path]] of the view `$context`.
|
||||
* If `$context` is not given, it will be looked for under the directory containing the view currently
|
||||
* being rendered (i.e., this happens when rendering a view within another view).
|
||||
*
|
||||
* @param string $view the view name. Please refer to [[Controller::findViewFile()]]
|
||||
* and [[Widget::findViewFile()]] on how to specify this parameter.
|
||||
* @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file.
|
||||
* @param object $context the context that the view should use for rendering the view. If null,
|
||||
* existing [[context]] will be used.
|
||||
* @param object $context the context to be assigned to the view and can later be accessed via [[context]]
|
||||
* in the view. If the context implements [[ViewContextInterface]], it may also be used to locate
|
||||
* the view file corresponding to a relative view name.
|
||||
* @return string the rendering result
|
||||
* @throws InvalidParamException if the view cannot be resolved or the view file does not exist.
|
||||
* @see renderFile()
|
||||
@ -148,10 +152,12 @@ class View extends Component
|
||||
* Finds the view file based on the given view name.
|
||||
* @param string $view the view name or the path alias of the view file. Please refer to [[render()]]
|
||||
* on how to specify this parameter.
|
||||
* @param object $context the context that the view should be used to search the view file. If null,
|
||||
* existing [[context]] will be used.
|
||||
* @param object $context the context to be assigned to the view and can later be accessed via [[context]]
|
||||
* in the view. If the context implements [[ViewContextInterface]], it may also be used to locate
|
||||
* the view file corresponding to a relative view name.
|
||||
* @return string the view file path. Note that the file may not exist.
|
||||
* @throws InvalidCallException if [[context]] is required and invalid.
|
||||
* @throws InvalidCallException if a relative view name is given while there is no active context to
|
||||
* determine the corresponding view file.
|
||||
*/
|
||||
protected function findViewFile($view, $context = null)
|
||||
{
|
||||
@ -168,16 +174,12 @@ class View extends Component
|
||||
} 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 {
|
||||
// context required
|
||||
if ($context === null) {
|
||||
$context = $this->context;
|
||||
}
|
||||
if ($context instanceof ViewContextInterface) {
|
||||
$file = $context->findViewFile($view);
|
||||
} else {
|
||||
throw new InvalidCallException("Unable to locate view file for view '$view': no active view context.");
|
||||
}
|
||||
throw new InvalidCallException("Unable to resolve view file for view '$view': no active view context.");
|
||||
}
|
||||
|
||||
if (pathinfo($file, PATHINFO_EXTENSION) !== '') {
|
||||
@ -213,6 +215,7 @@ class View extends Component
|
||||
public function renderFile($viewFile, $params = [], $context = null)
|
||||
{
|
||||
$viewFile = Yii::getAlias($viewFile);
|
||||
|
||||
if ($this->theme !== null) {
|
||||
$viewFile = $this->theme->applyTo($viewFile);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace yii\base;
|
||||
/**
|
||||
* ViewContextInterface is the interface that should implemented by classes who want to support relative view names.
|
||||
*
|
||||
* The method [[findViewFile()]] should be implemented to convert a relative view name into a file path.
|
||||
* The method [[getViewPath()]] should be implemented to return the view path that may be prefixed to a relative view name.
|
||||
*
|
||||
* @author Paul Klimov <klimov.paul@gmail.com>
|
||||
* @since 2.0
|
||||
@ -18,9 +18,7 @@ namespace yii\base;
|
||||
interface ViewContextInterface
|
||||
{
|
||||
/**
|
||||
* Finds the view file corresponding to the specified relative view name.
|
||||
* @param string $view a relative view name. The name does NOT start with a slash.
|
||||
* @return string the view file path. Note that the file may not exist.
|
||||
* @return string the view path that may be prefixed to a relative view name.
|
||||
*/
|
||||
public function findViewFile($view);
|
||||
public function getViewPath();
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ class Widget extends Component implements ViewContextInterface
|
||||
*
|
||||
* If the view name does not contain a file extension, it will use the default one `.php`.
|
||||
|
||||
* @param string $view the view name. Please refer to [[findViewFile()]] on how to specify a view name.
|
||||
* @param string $view the view name.
|
||||
* @param array $params the parameters (name-value pairs) that should be made available in the view.
|
||||
* @return string the rendering result.
|
||||
* @throws InvalidParamException if the view file does not exist.
|
||||
@ -206,15 +206,4 @@ class Widget extends Component implements ViewContextInterface
|
||||
|
||||
return dirname($class->getFileName()) . DIRECTORY_SEPARATOR . 'views';
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the view file based on the given view name.
|
||||
* File will be searched under [[viewPath]] directory.
|
||||
* @param string $view the view name.
|
||||
* @return string the view file path. Note that the file may not exist.
|
||||
*/
|
||||
public function findViewFile($view)
|
||||
{
|
||||
return $this->getViewPath() . DIRECTORY_SEPARATOR . $view;
|
||||
}
|
||||
}
|
||||
|
@ -38,11 +38,6 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont
|
||||
* @event \yii\base\MailEvent an event raised right after send.
|
||||
*/
|
||||
const EVENT_AFTER_SEND = 'afterSend';
|
||||
/**
|
||||
* @var string directory containing view files for this email messages.
|
||||
* This can be specified as an absolute path or path alias.
|
||||
*/
|
||||
public $viewPath = '@app/mail';
|
||||
/**
|
||||
* @var string|boolean HTML layout view name. This is the layout used to render HTML mail body.
|
||||
* The property can take the following values:
|
||||
@ -104,6 +99,10 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont
|
||||
* @var \yii\base\View|array view instance or its array configuration.
|
||||
*/
|
||||
private $_view = [];
|
||||
/**
|
||||
* @var string the directory containing view files for composing mail messages.
|
||||
*/
|
||||
private $_viewPath;
|
||||
|
||||
/**
|
||||
* @param array|View $view view instance or its array configuration that will be used to
|
||||
@ -159,7 +158,7 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont
|
||||
* The view to be rendered can be specified in one of the following formats:
|
||||
*
|
||||
* - path alias (e.g. "@app/mail/contact");
|
||||
* - a relative view name (e.g. "contact"): the actual view file will be resolved by [[findViewFile()]]
|
||||
* - a relative view name (e.g. "contact") located under [[viewPath]].
|
||||
*
|
||||
* @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file.
|
||||
* @return MessageInterface message instance.
|
||||
@ -319,14 +318,24 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the view file corresponding to the specified relative view name.
|
||||
* This method will return the view file by prefixing the view name with [[viewPath]].
|
||||
* @param string $view a relative view name. The name does NOT start with a slash.
|
||||
* @return string the view file path. Note that the file may not exist.
|
||||
* @return string the directory that contains the view files for composing mail messages
|
||||
* Defaults to '@app/mail'.
|
||||
*/
|
||||
public function findViewFile($view)
|
||||
public function getViewPath()
|
||||
{
|
||||
return Yii::getAlias($this->viewPath) . DIRECTORY_SEPARATOR . $view;
|
||||
if ($this->_viewPath === null) {
|
||||
$this->setViewPath('@app/mail');
|
||||
}
|
||||
return $this->_viewPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path the directory that contains the view files for composing mail messages
|
||||
* This can be specified as an absolute path or a path alias.
|
||||
*/
|
||||
public function setViewPath($path)
|
||||
{
|
||||
$this->_viewPath = Yii::getAlias($path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user