📜 ⬆️ ⬇️

Automatic connection of css and js files in Yii

Good day.

This time I want to talk about how to automatically connect css and js files in Yii. The idea is to bind the appropriate folder with resources (css, js, images) to each file of the form. This is convenient because in most cases, specific “assets” are used for specific files of the form.

And so, closer to the code. Expand the Controller class (which is probably in your “components” folder :), adding the following functionality to it:

/** * 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]; } 

Let us see how this works. In the "beforeRender ($ view)" methods are called before rendering:
')
 //   (      assets/{controllerName}/{viewName}/js/index.js) _setupScript($view) //   (      assets/{controllerName}/{viewName}/css/index.css) _setupCss($view) 

They automatically connect the corresponding css and js files for the specified view file.

Further, here in "beforeRender ()" additional methods are launched for connecting styles and scripts (if defined). The difference of these methods from the previous ones is that they are tied to a specific file of the form. Those. the name of the file of the form participates in the formation of the name of the corresponding method; for example, the name of the method for scripts is made up of the rule: "_setupScript" + "Name of the file in camel notation", for styles: "_setupCss" + "Name of the file in camel notation".

Also now the following methods are available to us:

Methods that return URLs to published resources:
 getScriptUrl($view, $fileName) //  URL   js  getCssUrl($view, $fileName) //  URL   css  getImageUrl($view, $fileName) //  URL     

Methods that return real resource paths (in the assets in protected folder):
 getScriptPath($view, $fileName) //    js  getCssPath($view, $fileName) //    css  getImagePath($view, $fileName) //      

And common methods:
 getAssetsAlias($view) //     "assets",    protected getPublishedAssetsUrl($view) //  URL     "assets" 

Directory names (for js, css files and images) and default files are defined in the controller class properties.
 protected $_cssDirName = 'css'; protected $_defaultCssFile = 'index.css'; protected $_scriptDirName = 'js'; protected $_defaultScriptFile = 'index.js'; protected $_imageDirName = 'images'; 

Accordingly, you can change them to the ones you need. Optionally, you can put them in the application configuration by making simple modifications in the code.

Using.

You can either override the "_setupCss ($ view)" method if you need to include css files for all possible controller type files:
 /** * 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')); } 

Or define the method "_setupCss" + "The name of the file in the camel notation", if you need to include css files for a specific file of the form:
 /** * Setup css files * * @param string $view * @return void */ protected function _setupCssRegistration($view) { Yii::app()->clientScript->registerCssFile($this->getCssUrl($view, 'my_css_file.css')); } 

This method will be called only when rendering “registration”

Pictures can be obtained as follows:
 CHtml::image($this->getImageUrl($view)); 


This is all. Thank you all for your attention.

Source: https://habr.com/ru/post/150885/


All Articles