Доброго времени суток.
На этот раз хочу, рассказать о способе автоматического подключения css и js файлов в Yii. Идея заключается в том, что бы к каждому файлу вида привязывать соответствующую папку с ресурсами (css, js, images). Это удобно, т.к. в большенстве случаев конкретные «assets» используются для конкретных файлов вида.
И так, ближе к коду. Расширим класс Controller (который наверняка лежит у вас в папке «components» :)), добавив в него следующую функциональность:
Разберем как это работает. В «beforeRender($view)» перед рендерингом вызываются методы:
В них происходит автоматическое подключение соответствующих css и js файлов для заданного файла вида.
Далее, здесь же в «beforeRender()» запускаются дополнительные методы для подключения стилей и скриптов (если они определены). Отличие этих методов от предыдущих в том, что они привязаны к конкретному файлу вида. Т.е. в формировании названия соответствующего метода участвует имя файла вида, например, имя метода для скриптов складывается из правила: "_setupScript" + «Имя файла вида в верблюжьей нотации», для стилей: "_setupCss" + «Имя файла вида в верблюжьей нотации».
Так же теперь нам доступны следующие методы:
Методы возвращающие URL адреса до опубликованных ресурсов:
Методы возвращающие реальные пути ресурсов (в папке assets в protected):
И общие методы:
Имена директорий (для js, css файлов и изображений) и файлов по умолчанию определены в свойствах класса контроллера.
Соответственно вы можете изменить их на нужные вам. По желанию можно вынести их в конфиг приложения, проделав несложные модификации в коде.
Вы можете либо переопределить метод "_setupCss($view)", если вам нужно подключать css файлы для всех возможных файлов вида контроллера:
Либо определить метод "_setupCss" + «Имя файла вида в верблюжьей нотации», если вам нужно подключать css файлы для конкретного файла вида:
Данный метод будет вызван только при рендеринге «registration»
Картинки можно получать так:
На это всё. Всем спасибо за внимание.
На этот раз хочу, рассказать о способе автоматического подключения css и js файлов в Yii. Идея заключается в том, что бы к каждому файлу вида привязывать соответствующую папку с ресурсами (css, js, images). Это удобно, т.к. в большенстве случаев конкретные «assets» используются для конкретных файлов вида.
И так, ближе к коду. Расширим класс Controller (который наверняка лежит у вас в папке «components» :)), добавив в него следующую функциональность:
/** * Array of paths of assets * @var array */ private $_assetsPaths = array(); /** * Array of asset Url * @var array */ private $_assetsUrl = array(); /** * Name of directory for css files * @var strign */ protected $_cssDirName = 'css'; /** * Default file name of css * @var string */ protected $_defaultCssFile = 'index.css'; /** * Name of directory for script files * @var strign */ protected $_scriptDirName = 'js'; /** * Default file name of script * @var string */ protected $_defaultScriptFile = 'index.js'; /** * Name of directory for images * @var strign */ protected $_imageDirName = 'images'; /** * This method is invoked at the beginning of {@link render()}. * * @param string $view the view to be rendered * @return boolean whether the view should be rendered. */ protected function beforeRender($view) { $this->_setupScript($view); $this->_setupCss($view); $viewCamelCase = preg_replace_callback( '/_([a-z0-9])/', function ($char) { return strtoupper($char[1]); }, ucfirst($view) ); $methodScript = '_setupScript' . $viewCamelCase; if (method_exists($this, $methodScript)) { $this->$methodScript($view); } $methodCss = '_setupCss' . $viewCamelCase; if (method_exists($this, $methodCss)) { $this->$methodCss($view); } return true; } /** * Setup script files * * @param string $view * @return void */ protected function _setupScript($view) { $scriptRealPath = $this->getScriptPath($view, $this->_defaultScriptFile); if (is_file($scriptRealPath)) { $scriptPublishedUrl = $this->getScriptUrl($view, $this->_defaultScriptFile); Yii::app()->clientScript->registerScriptFile($scriptPublishedUrl); } } /** * Setup css files * * @param string $view * @return void */ protected function _setupCss($view) { $cssRealPath = $this->getCssPath($view, $this->_defaultCssFile); if (is_file($cssRealPath)) { $cssPublishedUrl = $this->getCssUrl($view, $this->_defaultCssFile); Yii::app()->clientScript->registerCssFile($cssPublishedUrl); } } /** * Returns the published script URL * * @param string $view * @param string $fileName * @return string|false */ public function getScriptUrl($view, $fileName) { if (($publishedUrl = $this->getPublishedAssetsUrl($view))) { return $publishedUrl . '/' . $this->_scriptDirName . '/' . $fileName; } return false; } /** * Returns the real script Path * * @param string $fileName * @param string $view * @return string|false */ public function getScriptPath($view, $fileName) { if (($path = $this->getAssetsPath($view))) { return $path . DIRECTORY_SEPARATOR . $this->_scriptDirName . DIRECTORY_SEPARATOR . $fileName; } return false; } /** * Returns the published css URL * * @param string $view * @param string $fileName * @return string|false */ public function getCssUrl($view, $fileName) { if (($publishedUrl = $this->getPublishedAssetsUrl($view))) { return $publishedUrl . '/' . $this->_cssDirName . '/' . $fileName; } return false; } /** * Returns the real css path * * @param string $view * @param string $fileName * @return string|false */ public function getCssPath($view, $fileName) { if (($path = $this->getAssetsPath($view))) { return $path . DIRECTORY_SEPARATOR . $this->_cssDirName . DIRECTORY_SEPARATOR . $fileName; } return false; } /** * Returns the published image URL * * @param string $view * @param string $fileName * @return string|false */ public function getImageUrl($view, $fileName) { if (($publishedUrl = $this->getPublishedAssetsUrl($view))) { return $publishedUrl . '/' . $this->_imageDirName . '/' . $fileName; } return false; } /** * Returns the real image path * * @param string $view * @param string $fileName * @return string|false */ public function getImagePath($view, $fileName) { if (($path = $this->getAssetsPath($view))) { return $path . DIRECTORY_SEPARATOR . $this->_imageDirName . DIRECTORY_SEPARATOR . $fileName; } return false; } /** * Returns alias of assets * * @param string $view * @return string|false */ protected function getAssetsPath($view) { if (!array_key_exists($view, $this->_assetsPaths)) { $assetPath = false; $viewPath = $this->getViewFile($view); if ($viewPath) { if (($pos = strrpos($viewPath, DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR)) !== false) { $extension = ($renderer=Yii::app()->getViewRenderer()) !== null ? $renderer->fileExtension : '.php'; $assetPath = substr($viewPath, 0, $pos) . DIRECTORY_SEPARATOR . 'assets' . substr($viewPath, $pos + 1 + strlen('views')); $assetPath = dirname($assetPath) . DIRECTORY_SEPARATOR . basename($assetPath, $extension); } } $this->_assetsPaths[$view] = $assetPath; } return $this->_assetsPaths[$view]; } /** * Returns the published asset URL * * @param string $view * @return string|false */ public function getPublishedAssetsUrl($view) { if (!array_key_exists($view, $this->_assetsUrl)) { $assetsUrl = false; $assetsPath = $this->getAssetsPath($view); if ($assetsPath) { $assetsUrl = Yii::app()->assetManager->publish($assetsPath); } $this->_assetsUrl[$view] = $assetsUrl; } return $this->_assetsUrl[$view]; }
Разберем как это работает. В «beforeRender($view)» перед рендерингом вызываются методы:
// Подключение скриптов (по умолчанию подключает файл по пути assets/{controllerName}/{viewName}/js/index.js) _setupScript($view) // Подключение стилей (по умолчанию подключает файл по пути assets/{controllerName}/{viewName}/css/index.css) _setupCss($view)
В них происходит автоматическое подключение соответствующих css и js файлов для заданного файла вида.
Далее, здесь же в «beforeRender()» запускаются дополнительные методы для подключения стилей и скриптов (если они определены). Отличие этих методов от предыдущих в том, что они привязаны к конкретному файлу вида. Т.е. в формировании названия соответствующего метода участвует имя файла вида, например, имя метода для скриптов складывается из правила: "_setupScript" + «Имя файла вида в верблюжьей нотации», для стилей: "_setupCss" + «Имя файла вида в верблюжьей нотации».
Так же теперь нам доступны следующие методы:
Методы возвращающие URL адреса до опубликованных ресурсов:
getScriptUrl($view, $fileName) // возвращает URL адрес до js файла getCssUrl($view, $fileName) // возвращает URL адрес до css файла getImageUrl($view, $fileName) // возвращает URL адрес до файла изображения
Методы возвращающие реальные пути ресурсов (в папке assets в protected):
getScriptPath($view, $fileName) // возвращает путь до js файл getCssPath($view, $fileName) // возвращает путь до css файл getImagePath($view, $fileName) // возвращает путь до файл изображения
И общие методы:
getAssetsAlias($view) // возвращает алиас до папки "assets", которая лежит в protected getPublishedAssetsUrl($view) // возвращает URL адрес до опубликованной директории "assets"
Имена директорий (для js, css файлов и изображений) и файлов по умолчанию определены в свойствах класса контроллера.
protected $_cssDirName = 'css'; protected $_defaultCssFile = 'index.css'; protected $_scriptDirName = 'js'; protected $_defaultScriptFile = 'index.js'; protected $_imageDirName = 'images';
Соответственно вы можете изменить их на нужные вам. По желанию можно вынести их в конфиг приложения, проделав несложные модификации в коде.
Использование.
Вы можете либо переопределить метод "_setupCss($view)", если вам нужно подключать css файлы для всех возможных файлов вида контроллера:
/** * Setup css files * * @param string $view * @return void */ protected function _setupCss($view) { parent::_setupCss($view); // будет искать my_css_file.css для каждого файла вида Yii::app()->clientScript->registerCssFile($this->getCssUrl($view, 'my_css_file.css')); }
Либо определить метод "_setupCss" + «Имя файла вида в верблюжьей нотации», если вам нужно подключать css файлы для конкретного файла вида:
/** * Setup css files * * @param string $view * @return void */ protected function _setupCssRegistration($view) { Yii::app()->clientScript->registerCssFile($this->getCssUrl($view, 'my_css_file.css')); }
Данный метод будет вызван только при рендеринге «registration»
Картинки можно получать так:
CHtml::image($this->getImageUrl($view));
На это всё. Всем спасибо за внимание.
