Commit 41ea9485 by Qiang Xue

refactoring and documentation for asset/script management.

parent 4e8f9cea
...@@ -10,6 +10,7 @@ namespace yii\base; ...@@ -10,6 +10,7 @@ namespace yii\base;
use Yii; use Yii;
use yii\base\Application; use yii\base\Application;
use yii\helpers\FileHelper; use yii\helpers\FileHelper;
use yii\helpers\Html;
/** /**
* View represents a view object in the MVC pattern. * View represents a view object in the MVC pattern.
...@@ -22,22 +23,48 @@ use yii\helpers\FileHelper; ...@@ -22,22 +23,48 @@ use yii\helpers\FileHelper;
class View extends Component class View extends Component
{ {
/** /**
* @event Event an event that is triggered by [[renderFile()]] right before it renders a view file. * @event ViewEvent an event that is triggered by [[renderFile()]] right before it renders a view file.
*/ */
const EVENT_BEFORE_RENDER = 'beforeRender'; const EVENT_BEFORE_RENDER = 'beforeRender';
/** /**
* @event Event an event that is triggered by [[renderFile()]] right after it renders a view file. * @event ViewEvent an event that is triggered by [[renderFile()]] right after it renders a view file.
*/ */
const EVENT_AFTER_RENDER = 'afterRender'; const EVENT_AFTER_RENDER = 'afterRender';
/** /**
* @var object the object that owns this view. This can be a controller, a widget, or any other object. * The location of registered JavaScript code block or files.
* This means the location is in the head section.
*/ */
public $context; const POS_HEAD = 1;
/**
* The location of registered JavaScript code block or files.
* This means the location is at the beginning of the body section.
*/
const POS_BEGIN = 2;
/**
* The location of registered JavaScript code block or files.
* This means the location is at the end of the body section.
*/
const POS_END = 3;
/**
* This is internally used as the placeholder for receiving the content registered for the head section.
*/
const PL_HEAD = '<![CDATA[YII-BLOCK-HEAD]]>';
/**
* This is internally used as the placeholder for receiving the content registered for the beginning of the body section.
*/
const PL_BODY_BEGIN = '<![CDATA[YII-BLOCK-BODY-BEGIN]]>';
/** /**
* @var ViewContent * This is internally used as the placeholder for receiving the content registered for the end of the body section.
*/ */
public $page; const PL_BODY_END = '<![CDATA[YII-BLOCK-BODY-END]]>';
/**
* @var object the context under which the [[renderFile()]] method is being invoked.
* This can be a controller, a widget, or any other object.
*/
public $context;
/** /**
* @var mixed custom parameters that are shared among view templates. * @var mixed custom parameters that are shared among view templates.
*/ */
...@@ -48,32 +75,75 @@ class View extends Component ...@@ -48,32 +75,75 @@ class View extends Component
*/ */
public $renderer; public $renderer;
/** /**
* @var Theme|array the theme object or the configuration array for creating the theme. * @var Theme|array the theme object or the configuration array for creating the theme object.
* If not set, it means theming is not enabled. * If not set, it means theming is not enabled.
*/ */
public $theme; public $theme;
/** /**
* @var array a list of named output blocks. The keys are the block names and the values * @var array a list of named output blocks. The keys are the block names and the values
* are the corresponding block content. You can call [[beginBlock()]] and [[endBlock()]] * are the corresponding block content. You can call [[beginBlock()]] and [[endBlock()]]
* to capture small fragments of a view. They can be later accessed at somewhere else * to capture small fragments of a view. They can be later accessed somewhere else
* through this property. * through this property.
*/ */
public $blocks; public $blocks;
/** /**
* @var Widget[] the widgets that are currently being rendered (not ended). This property * @var Widget[] the widgets that are currently being rendered (not ended). This property
* is maintained by [[beginWidget()]] and [[endWidget()]] methods. Do not modify it. * is maintained by [[beginWidget()]] and [[endWidget()]] methods. Do not modify it directly.
* @internal
*/ */
public $widgetStack = array(); public $widgetStack = array();
/** /**
* @var array a list of currently active fragment cache widgets. This property * @var array a list of currently active fragment cache widgets. This property
* is used internally to implement the content caching feature. Do not modify it. * is used internally to implement the content caching feature. Do not modify it directly.
* @internal
*/ */
public $cacheStack = array(); public $cacheStack = array();
/** /**
* @var array a list of placeholders for embedding dynamic contents. This property * @var array a list of placeholders for embedding dynamic contents. This property
* is used internally to implement the content caching feature. Do not modify it. * is used internally to implement the content caching feature. Do not modify it directly.
* @internal
*/ */
public $dynamicPlaceholders = array(); public $dynamicPlaceholders = array();
/**
* @var array the registered asset bundles. The keys are the bundle names, and the values
* are the corresponding [[AssetBundle]] objects.
* @see registerAssetBundle
*/
public $assetBundles;
/**
* @var string the page title
*/
public $title;
/**
* @var array the registered meta tags.
* @see registerMetaTag
*/
public $metaTags;
/**
* @var array the registered link tags.
* @see registerLinkTag
*/
public $linkTags;
/**
* @var array the registered CSS code blocks.
* @see registerCss
*/
public $css;
/**
* @var array the registered CSS files.
* @see registerCssFile
*/
public $cssFiles;
/**
* @var array the registered JS code blocks
* @see registerJs
*/
public $js;
/**
* @var array the registered JS files.
* @see registerJsFile
*/
public $jsFiles;
/** /**
...@@ -88,11 +158,6 @@ class View extends Component ...@@ -88,11 +158,6 @@ class View extends Component
if (is_array($this->theme)) { if (is_array($this->theme)) {
$this->theme = Yii::createObject($this->theme); $this->theme = Yii::createObject($this->theme);
} }
if (is_array($this->page)) {
$this->page = Yii::createObject($this->page);
} else {
$this->page = new ViewContent;
}
} }
/** /**
...@@ -445,4 +510,273 @@ class View extends Component ...@@ -445,4 +510,273 @@ class View extends Component
{ {
$this->endWidget(); $this->endWidget();
} }
private $_assetManager;
/**
* Registers the asset manager being used by this view object.
* @return \yii\web\AssetManager the asset manager. Defaults to the "assetManager" application component.
*/
public function getAssetManager()
{
return $this->_assetManager ?: Yii::$app->getAssetManager();
}
/**
* Sets the asset manager.
* @param \yii\web\AssetManager $value the asset manager
*/
public function setAssetManager($value)
{
$this->_assetManager = $value;
}
/**
* Marks the beginning of an HTML page.
*/
public function beginPage()
{
ob_start();
ob_implicit_flush(false);
}
/**
* Marks the ending of an HTML page.
*/
public function endPage()
{
$content = ob_get_clean();
echo strtr($content, array(
self::PL_HEAD => $this->renderHeadHtml(),
self::PL_BODY_BEGIN => $this->renderBodyBeginHtml(),
self::PL_BODY_END => $this->renderBodyEndHtml(),
));
unset(
$this->assetBundles,
$this->metaTags,
$this->linkTags,
$this->css,
$this->cssFiles,
$this->js,
$this->jsFiles
);
}
/**
* Marks the beginning of an HTML body section.
*/
public function beginBody()
{
echo self::PL_BODY_BEGIN;
}
/**
* Marks the ending of an HTML body section.
*/
public function endBody()
{
echo self::PL_BODY_END;
}
/**
* Marks the position of an HTML head section.
*/
public function head()
{
echo self::PL_HEAD;
}
/**
* Registers the named asset bundle.
* All dependent asset bundles will be registered.
* @param string $name the name of the asset bundle.
* @throws InvalidConfigException if the asset bundle does not exist or a cyclic dependency is detected
*/
public function registerAssetBundle($name)
{
if (!isset($this->assetBundles[$name])) {
$am = $this->getAssetManager();
$bundle = $am->getBundle($name);
if ($bundle !== null) {
$this->assetBundles[$name] = false;
$bundle->registerAssets($this);
$this->assetBundles[$name] = true;
} else {
throw new InvalidConfigException("Unknown asset bundle: $name");
}
} elseif ($this->assetBundles[$name] === false) {
throw new InvalidConfigException("A cyclic dependency is detected for bundle '$name'.");
}
}
/**
* Registers a meta tag.
* @param array $options the HTML attributes for the meta tag.
* @param string $key the key that identifies the meta tag. If two meta tags are registered
* with the same key, the latter will overwrite the former. If this is null, the new meta tag
* will be appended to the existing ones.
*/
public function registerMetaTag($options, $key = null)
{
if ($key === null) {
$this->metaTags[] = Html::tag('meta', '', $options);
} else {
$this->metaTags[$key] = Html::tag('meta', '', $options);
}
}
/**
* Registers a link tag.
* @param array $options the HTML attributes for the link tag.
* @param string $key the key that identifies the link tag. If two link tags are registered
* with the same key, the latter will overwrite the former. If this is null, the new link tag
* will be appended to the existing ones.
*/
public function registerLinkTag($options, $key = null)
{
if ($key === null) {
$this->linkTags[] = Html::tag('link', '', $options);
} else {
$this->linkTags[$key] = Html::tag('link', '', $options);
}
}
/**
* Registers a CSS code block.
* @param string $css the CSS code block to be registered
* @param array $options the HTML attributes for the style tag.
* @param string $key the key that identifies the CSS code block. If null, it will use
* $css as the key. If two CSS code blocks are registered with the same key, the latter
* will overwrite the former.
*/
public function registerCss($css, $options = array(), $key = null)
{
$key = $key ?: $css;
$this->css[$key] = Html::style($css, $options);
}
/**
* Registers a CSS file.
* @param string $url the CSS file to be registered.
* @param array $options the HTML attributes for the link tag.
* @param string $key the key that identifies the CSS script file. If null, it will use
* $url as the key. If two CSS files are registered with the same key, the latter
* will overwrite the former.
*/
public function registerCssFile($url, $options = array(), $key = null)
{
$key = $key ?: $url;
$this->cssFiles[$key] = Html::cssFile($url, $options);
}
/**
* Registers a JS code block.
* @param string $js the JS code block to be registered
* @param array $options the HTML attributes for the script tag. A special option
* named "position" is supported which specifies where the JS script tag should be inserted
* in a page. The possible values of "position" are:
*
* - [[POS_HEAD]]: in the head section
* - [[POS_BEGIN]]: at the beginning of the body section
* - [[POS_END]]: at the end of the body section
*
* @param string $key the key that identifies the JS code block. If null, it will use
* $js as the key. If two JS code blocks are registered with the same key, the latter
* will overwrite the former.
*/
public function registerJs($js, $options = array(), $key = null)
{
$position = isset($options['position']) ? $options['position'] : self::POS_END;
unset($options['position']);
$key = $key ?: $js;
$this->js[$position][$key] = Html::script($js, $options);
}
/**
* Registers a JS file.
* @param string $url the JS file to be registered.
* @param array $options the HTML attributes for the script tag. A special option
* named "position" is supported which specifies where the JS script tag should be inserted
* in a page. The possible values of "position" are:
*
* - [[POS_HEAD]]: in the head section
* - [[POS_BEGIN]]: at the beginning of the body section
* - [[POS_END]]: at the end of the body section
*
* @param string $key the key that identifies the JS script file. If null, it will use
* $url as the key. If two JS files are registered with the same key, the latter
* will overwrite the former.
*/
public function registerJsFile($url, $options = array(), $key = null)
{
$position = isset($options['position']) ? $options['position'] : self::POS_END;
unset($options['position']);
$key = $key ?: $url;
$this->jsFiles[$position][$key] = Html::jsFile($url, $options);
}
/**
* Renders the content to be inserted in the head section.
* The content is rendered using the registered meta tags, link tags, CSS/JS code blocks and files.
* @return string the rendered content
*/
protected function renderHeadHtml()
{
$lines = array();
if (!empty($this->metaTags)) {
$lines[] = implode("\n", $this->cssFiles);
}
if (!empty($this->linkTags)) {
$lines[] = implode("\n", $this->cssFiles);
}
if (!empty($this->cssFiles)) {
$lines[] = implode("\n", $this->cssFiles);
}
if (!empty($this->css)) {
$lines[] = implode("\n", $this->css);
}
if (!empty($this->jsFiles[self::POS_HEAD])) {
$lines[] = implode("\n", $this->jsFiles[self::POS_HEAD]);
}
if (!empty($this->js[self::POS_HEAD])) {
$lines[] = implode("\n", $this->js[self::POS_HEAD]);
}
return implode("\n", $lines);
}
/**
* Renders the content to be inserted at the beginning of the body section.
* The content is rendered using the registered JS code blocks and files.
* @return string the rendered content
*/
protected function renderBodyBeginHtml()
{
$lines = array();
if (!empty($this->jsFiles[self::POS_BEGIN])) {
$lines[] = implode("\n", $this->jsFiles[self::POS_BEGIN]);
}
if (!empty($this->js[self::POS_BEGIN])) {
$lines[] = implode("\n", $this->js[self::POS_BEGIN]);
}
return implode("\n", $lines);
}
/**
* Renders the content to be inserted at the end of the body section.
* The content is rendered using the registered JS code blocks and files.
* @return string the rendered content
*/
protected function renderBodyEndHtml()
{
$lines = array();
if (!empty($this->jsFiles[self::POS_END])) {
$lines[] = implode("\n", $this->jsFiles[self::POS_END]);
}
if (!empty($this->js[self::POS_END])) {
$lines[] = implode("\n", $this->js[self::POS_END]);
}
return implode("\n", $lines);
}
} }
\ No newline at end of file
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\base;
use Yii;
use yii\helpers\Html;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class ViewContent extends Component
{
const POS_HEAD = 1;
const POS_BEGIN = 2;
const POS_END = 3;
const TOKEN_HEAD = '<![CDATA[YII-BLOCK-HEAD]]>';
const TOKEN_BODY_BEGIN = '<![CDATA[YII-BLOCK-BODY-BEGIN]]>';
const TOKEN_BODY_END = '<![CDATA[YII-BLOCK-BODY-END]]>';
public $assetBundles;
public $title;
public $metaTags;
public $linkTags;
public $css;
public $cssFiles;
public $js;
public $jsFiles;
public $jsInHead;
public $jsFilesInHead;
public $jsInBody;
public $jsFilesInBody;
public function reset()
{
$this->assetBundles = null;
$this->title = null;
$this->metaTags = null;
$this->linkTags = null;
$this->css = null;
$this->cssFiles = null;
$this->js = null;
$this->jsFiles = null;
$this->jsInHead = null;
$this->jsFilesInHead = null;
$this->jsInBody = null;
$this->jsFilesInBody = null;
}
private $_assetManager;
/**
* @return \yii\web\AssetManager
*/
public function getAssetManager()
{
return $this->_assetManager ?: Yii::$app->getAssets();
}
public function setAssetManager($value)
{
$this->_assetManager = $value;
}
public function begin()
{
ob_start();
ob_implicit_flush(false);
}
public function end()
{
$content = ob_get_clean();
echo $this->populate($content);
}
public function beginBody()
{
echo self::TOKEN_BODY_BEGIN;
}
public function endBody()
{
echo self::TOKEN_BODY_END;
}
public function head()
{
echo self::TOKEN_HEAD;
}
public function registerAssetBundle($name)
{
if (!isset($this->assetBundles[$name])) {
$am = $this->getAssetManager();
$bundle = $am->getBundle($name);
if ($bundle !== null) {
$this->assetBundles[$name] = false;
$bundle->registerAssets($this, $am);
$this->assetBundles[$name] = true;
} else {
throw new InvalidConfigException("Unknown asset bundle: $name");
}
} elseif ($this->assetBundles[$name] === false) {
throw new InvalidConfigException("A cyclic dependency is detected for bundle '$name'.");
}
}
public function registerMetaTag($options, $key = null)
{
if ($key === null) {
$this->metaTags[] = Html::tag('meta', '', $options);
} else {
$this->metaTags[$key] = Html::tag('meta', '', $options);
}
}
public function registerLinkTag($options, $key = null)
{
if ($key === null) {
$this->linkTags[] = Html::tag('link', '', $options);
} else {
$this->linkTags[$key] = Html::tag('link', '', $options);
}
}
public function registerCss($css, $options = array(), $key = null)
{
$key = $key ?: $css;
$this->css[$key] = Html::style($css, $options);
}
public function registerCssFile($url, $options = array(), $key = null)
{
$key = $key ?: $url;
$this->cssFiles[$key] = Html::cssFile($url, $options);
}
public function registerJs($js, $options = array(), $key = null)
{
$position = isset($options['position']) ? $options['position'] : self::POS_END;
unset($options['position']);
$key = $key ?: $js;
$html = Html::script($js, $options);
if ($position == self::POS_END) {
$this->js[$key] = $html;
} elseif ($position == self::POS_HEAD) {
$this->jsInHead[$key] = $html;
} elseif ($position == self::POS_BEGIN) {
$this->jsInBody[$key] = $html;
} else {
throw new InvalidParamException("Unknown position: $position");
}
}
public function registerJsFile($url, $options = array(), $key = null)
{
$position = isset($options['position']) ? $options['position'] : self::POS_END;
unset($options['position']);
$key = $key ?: $url;
$html = Html::jsFile($url, $options);
if ($position == self::POS_END) {
$this->jsFiles[$key] = $html;
} elseif ($position == self::POS_HEAD) {
$this->jsFilesInHead[$key] = $html;
} elseif ($position == self::POS_BEGIN) {
$this->jsFilesInBody[$key] = $html;
} else {
throw new InvalidParamException("Unknown position: $position");
}
}
protected function populate($content)
{
return strtr($content, array(
self::TOKEN_HEAD => $this->getHeadHtml(),
self::TOKEN_BODY_BEGIN => $this->getBodyBeginHtml(),
self::TOKEN_BODY_END => $this->getBodyEndHtml(),
));
}
protected function getHeadHtml()
{
$lines = array();
if (!empty($this->metaTags)) {
$lines[] = implode("\n", $this->cssFiles);
}
if (!empty($this->linkTags)) {
$lines[] = implode("\n", $this->cssFiles);
}
if (!empty($this->cssFiles)) {
$lines[] = implode("\n", $this->cssFiles);
}
if (!empty($this->css)) {
$lines[] = implode("\n", $this->css);
}
if (!empty($this->jsFilesInHead)) {
$lines[] = implode("\n", $this->jsFilesInHead);
}
if (!empty($this->jsInHead)) {
$lines[] = implode("\n", $this->jsInHead);
}
return implode("\n", $lines);
}
protected function getBodyBeginHtml()
{
$lines = array();
if (!empty($this->jsFilesInBody)) {
$lines[] = implode("\n", $this->jsFilesInBody);
}
if (!empty($this->jsInHead)) {
$lines[] = implode("\n", $this->jsInBody);
}
return implode("\n", $lines);
}
protected function getBodyEndHtml()
{
$lines = array();
if (!empty($this->jsFiles)) {
$lines[] = implode("\n", $this->jsFiles);
}
if (!empty($this->js)) {
$lines[] = implode("\n", $this->js);
}
return implode("\n", $lines);
}
}
\ No newline at end of file
...@@ -101,9 +101,9 @@ class Application extends \yii\base\Application ...@@ -101,9 +101,9 @@ class Application extends \yii\base\Application
* Returns the asset manager. * Returns the asset manager.
* @return AssetManager the asset manager component * @return AssetManager the asset manager component
*/ */
public function getAssets() public function getAssetManager()
{ {
return $this->getComponent('assets'); return $this->getComponent('assetManager');
} }
/** /**
...@@ -126,7 +126,7 @@ class Application extends \yii\base\Application ...@@ -126,7 +126,7 @@ class Application extends \yii\base\Application
'user' => array( 'user' => array(
'class' => 'yii\web\User', 'class' => 'yii\web\User',
), ),
'assets' => array( 'assetManager' => array(
'class' => 'yii\web\AssetManager', 'class' => 'yii\web\AssetManager',
), ),
)); ));
......
...@@ -12,6 +12,14 @@ use yii\base\InvalidConfigException; ...@@ -12,6 +12,14 @@ use yii\base\InvalidConfigException;
use yii\base\Object; use yii\base\Object;
/** /**
* AssetBundle represents a collection of asset files, such as CSS, JS, images.
*
* Each asset bundle has a unique name that globally identifies it among all asset bundles
* used in an application.
*
* An asset bundle can depend on other asset bundles. When registering an asset bundle
* with a view, all its dependent asset bundles will be automatically registered.
*
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
...@@ -66,7 +74,7 @@ class AssetBundle extends Object ...@@ -66,7 +74,7 @@ class AssetBundle extends Object
* *
* Each JavaScript file may be associated with options. In this case, the array key * Each JavaScript file may be associated with options. In this case, the array key
* should be the JavaScript file path, while the corresponding array value should * should be the JavaScript file path, while the corresponding array value should
* be the option array. The options will be passed to [[ViewContent::registerJsFile()]]. * be the option array. The options will be passed to [[View::registerJsFile()]].
*/ */
public $js = array(); public $js = array();
/** /**
...@@ -78,7 +86,7 @@ class AssetBundle extends Object ...@@ -78,7 +86,7 @@ class AssetBundle extends Object
* *
* Each CSS file may be associated with options. In this case, the array key * Each CSS file may be associated with options. In this case, the array key
* should be the CSS file path, while the corresponding array value should * should be the CSS file path, while the corresponding array value should
* be the option array. The options will be passed to [[ViewContent::registerCssFile()]]. * be the option array. The options will be passed to [[View::registerCssFile()]].
*/ */
public $css = array(); public $css = array();
/** /**
...@@ -108,14 +116,20 @@ class AssetBundle extends Object ...@@ -108,14 +116,20 @@ class AssetBundle extends Object
} }
/** /**
* @param \yii\base\ViewContent $page * Registers the CSS and JS files with the given view.
* @param AssetManager $am * This method will first register all dependent asset bundles.
* @throws InvalidConfigException * It will then try to convert non-CSS or JS files (e.g. LESS, Sass) into the corresponding
* CSS or JS files using [[AssetManager::converter|asset converter]].
* @param \yii\base\View $view the view that the asset files to be registered with.
* @throws InvalidConfigException if [[baseUrl]] or [[basePath]] is not set when the bundle
* contains internal CSS or JS files.
*/ */
public function registerAssets($page, $am) public function registerAssets($view)
{ {
$am = $view->getAssetManager();
foreach ($this->depends as $name) { foreach ($this->depends as $name) {
$page->registerAssetBundle($name); $view->registerAssetBundle($name);
} }
if ($this->sourcePath !== null) { if ($this->sourcePath !== null) {
...@@ -128,23 +142,23 @@ class AssetBundle extends Object ...@@ -128,23 +142,23 @@ class AssetBundle extends Object
$js = is_string($options) ? $options : $js; $js = is_string($options) ? $options : $js;
if (strpos($js, '/') !== 0 && strpos($js, '://') === false) { if (strpos($js, '/') !== 0 && strpos($js, '://') === false) {
if (isset($this->basePath, $this->baseUrl)) { if (isset($this->basePath, $this->baseUrl)) {
$js = $converter->convert(ltrim($js, '/'), $this->basePath, $this->baseUrl); $js = $converter->convert($js, $this->basePath, $this->baseUrl);
} else { } else {
throw new InvalidConfigException('Both of the "baseUrl" and "basePath" properties must be set.'); throw new InvalidConfigException('Both of the "baseUrl" and "basePath" properties must be set.');
} }
} }
$page->registerJsFile($js, is_array($options) ? $options : array()); $view->registerJsFile($js, is_array($options) ? $options : array());
} }
foreach ($this->css as $css => $options) { foreach ($this->css as $css => $options) {
$css = is_string($options) ? $options : $css; $css = is_string($options) ? $options : $css;
if (strpos($css, '//') !== 0 && strpos($css, '://') === false) { if (strpos($css, '/') !== 0 && strpos($css, '://') === false) {
if (isset($this->basePath, $this->baseUrl)) { if (isset($this->basePath, $this->baseUrl)) {
$css = $converter->convert(ltrim($css, '/'), $this->basePath, $this->baseUrl); $css = $converter->convert($css, $this->basePath, $this->baseUrl);
} else { } else {
throw new InvalidConfigException('Both of the "baseUrl" and "basePath" properties must be set.'); throw new InvalidConfigException('Both of the "baseUrl" and "basePath" properties must be set.');
} }
} }
$page->registerCssFile($css, is_array($options) ? $options : array()); $view->registerCssFile($css, is_array($options) ? $options : array());
} }
} }
} }
\ No newline at end of file
...@@ -14,6 +14,7 @@ use yii\base\InvalidParamException; ...@@ -14,6 +14,7 @@ use yii\base\InvalidParamException;
use yii\helpers\FileHelper; use yii\helpers\FileHelper;
/** /**
* AssetManager manages asset bundles and asset publishing.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
...@@ -135,7 +136,8 @@ class AssetManager extends Component ...@@ -135,7 +136,8 @@ class AssetManager extends Component
private $_converter; private $_converter;
/** /**
* @return IAssetConverter * Returns the asset converter.
* @return IAssetConverter the asset converter.
*/ */
public function getConverter() public function getConverter()
{ {
...@@ -149,6 +151,12 @@ class AssetManager extends Component ...@@ -149,6 +151,12 @@ class AssetManager extends Component
return $this->_converter; return $this->_converter;
} }
/**
* Sets the asset converter.
* @param array|IAssetConverter $value the asset converter. This can be either
* an object implementing the [[IAssetConverter]] interface, or a configuration
* array that can be used to create the asset converter object.
*/
public function setConverter($value) public function setConverter($value)
{ {
$this->_converter = $value; $this->_converter = $value;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment