├── version ├── src ├── widgets │ ├── views │ │ ├── TextPage.php │ │ ├── FancyPanel.php │ │ ├── OrganizationLink.php │ │ ├── PoweredBy.php │ │ ├── LogoLink.php │ │ ├── faq │ │ │ ├── node.php │ │ │ └── root.php │ │ └── LoginForm.php │ ├── AlertWidget.php │ ├── SidebarMenu.php │ ├── Flashes.php │ ├── Faq.php │ ├── CopyrightYears.php │ ├── UserMenu.php │ ├── FancyPanel.php │ ├── OrganizationLink.php │ ├── PoweredBy.php │ ├── Markdown.php │ ├── SocialLinks.php │ ├── TextPage.php │ ├── LogoLink.php │ └── LoginForm.php ├── views │ ├── debug │ │ ├── summary.php │ │ └── detail.php │ └── settings │ │ └── index.php ├── models │ ├── OrientationInterface.php │ └── Settings.php ├── menus │ ├── AbstractMainMenu.php │ ├── AbstractFooterMenu.php │ ├── AbstractNavbarMenu.php │ ├── AbstractLanguageMenu.php │ ├── AbstractSidebarMenu.php │ ├── NavbarMenu.php │ ├── AbstractMenu.php │ └── MenuInterface.php ├── Module.php ├── FaqAsset.php ├── storage │ ├── SettingsStorageInterface.php │ └── SessionSettingsStorage.php ├── assets │ └── faq │ │ └── js │ │ ├── faq.min.js │ │ └── faq.js ├── GetManagerTrait.php ├── DetailedTheme.php ├── messages │ └── ru │ │ └── hiqdev.thememanager.php ├── debug │ └── Panel.php ├── controllers │ └── SettingsController.php ├── ThemeManager.php └── Theme.php ├── .scrutinizer.yml ├── docs └── readme │ ├── Installation.md │ ├── Configuration.md │ └── Idea.md ├── tests └── _bootstrap.php ├── config ├── i18n.php ├── params.php └── web.php ├── .gitignore ├── .travis.yml ├── phpunit.xml.dist ├── attic ├── AssetConverter.php ├── AssetManager.php └── View.php ├── chkipper.json ├── LICENSE ├── hidev.yml ├── composer.json ├── .php_cs ├── CHANGELOG.md ├── README.md └── history.md /version: -------------------------------------------------------------------------------- 1 | yii2-thememanager 0.4.0 2022-06-28 17:39:58 +0300 a01e793b2bb2e936c520bca06810dbd7e94ec0a9 2 | -------------------------------------------------------------------------------- /src/widgets/views/TextPage.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /src/widgets/views/FancyPanel.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | checks: 2 | php: 3 | code_rating: true 4 | duplication: true 5 | tools: 6 | php_code_coverage: 7 | enabled: true 8 | external_code_coverage: 9 | timeout: 600 10 | -------------------------------------------------------------------------------- /src/widgets/views/OrganizationLink.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/readme/Installation.md: -------------------------------------------------------------------------------- 1 | This package is not intended to be required directly in your project. 2 | Instead you should require theme(s) you've chosen and this package 3 | will get required as a dependency. 4 | 5 | Please see [hiqdev/hisite-template] as example of project using this theming 6 | library. 7 | 8 | [hiqdev/hisite-template]: https://github.com/hiqdev/hisite-template 9 | -------------------------------------------------------------------------------- /tests/_bootstrap.php: -------------------------------------------------------------------------------- 1 | 6 | data)): ?> 7 |
8 | Themes getCount() ?> 9 |
10 | 11 | -------------------------------------------------------------------------------- /src/widgets/AlertWidget.php: -------------------------------------------------------------------------------- 1 | widget)) { 16 | return Yii::createObject($this->widget)->run(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /config/i18n.php: -------------------------------------------------------------------------------- 1 | ['ru'], 13 | 'sourcePath' => dirname(__DIR__) . '/src', 14 | 'messagePath' => dirname(__DIR__) . '/src/messages', 15 | 'sort' => true, 16 | 'removeUnused' => true, 17 | ]; 18 | -------------------------------------------------------------------------------- /src/models/OrientationInterface.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | abstract class AbstractMainMenu extends AbstractMenu 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/menus/AbstractFooterMenu.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | abstract class AbstractFooterMenu extends AbstractMenu 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/menus/AbstractNavbarMenu.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | abstract class AbstractNavbarMenu extends AbstractMenu 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/menus/AbstractLanguageMenu.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | abstract class AbstractLanguageMenu extends AbstractMenu 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/menus/AbstractSidebarMenu.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | abstract class AbstractSidebarMenu extends AbstractMenu 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/widgets/SidebarMenu.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class SidebarMenu extends \yii\widgets\Menu 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/widgets/Flashes.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | class Flashes extends \yii\base\Widget 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/Module.php: -------------------------------------------------------------------------------- 1 | getManager()->isHomePage(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/widgets/views/PoweredBy.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # hidev internals 2 | /.hidev/composer.json 3 | /.hidev/composer.lock 4 | /.hidev/runtime 5 | /.hidev/vendor 6 | 7 | # local config 8 | /.env 9 | /hidev-local.yml 10 | 11 | # IDE & OS files 12 | .*.swp 13 | .DS_Store 14 | .buildpath 15 | .idea 16 | .project 17 | .settings 18 | Thumbs.db 19 | nbproject 20 | 21 | # composer internals 22 | /composer.lock 23 | /vendor 24 | 25 | # php-cs-fixer cache 26 | .php_cs.cache 27 | 28 | # phpunit generated files 29 | coverage.clover 30 | 31 | # Binaries 32 | chkipper.phar 33 | composer.phar 34 | ocular.phar 35 | php-cs-fixer.phar 36 | phpunit-skelgen.phar 37 | phpunit.phar 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.6 4 | - 7 5 | - 7.1 6 | - hhvm 7 | dist: trusty 8 | matrix: 9 | allow_failures: 10 | - 11 | php: hhvm 12 | cache: 13 | directories: 14 | - $HOME/.composer/cache 15 | before_install: 16 | - 'composer self-update' 17 | - 'composer --version' 18 | - 'wget http://hiqdev.com/hidev/hidev.phar -O hidev.phar && chmod a+x hidev.phar' 19 | - './hidev.phar --version' 20 | - './hidev.phar travis/before-install' 21 | sudo: false 22 | install: 23 | - './hidev.phar travis/install' 24 | script: 25 | - './hidev.phar travis/script' 26 | after_script: 27 | - './hidev.phar travis/after-script' 28 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests/unit/ 6 | 7 | 8 | 9 | 10 | ./src/ 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/widgets/views/LogoLink.php: -------------------------------------------------------------------------------- 1 | registerCss(<< h2 { 13 | position: absolute; 14 | top: -10000px; 15 | left: -10000px; 16 | } 17 | CSS 18 | ); 19 | 20 | ?> 21 | 22 | 23 | $url, 'class' =>'logo'], $options)) ?> 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/FaqAsset.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class Faq extends \yii\base\Widget 20 | { 21 | public $items = []; 22 | 23 | public function run() 24 | { 25 | FaqAsset::register($this->view); 26 | 27 | return $this->render('faq/root', [ 28 | 'items' => $this->items, 29 | ]); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/views/settings/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('hiqdev.thememanager', 'Theme Settings'); 6 | $this->params['breadcrumbs'][] = $this->title; 7 | 8 | ?> 9 |
10 |
11 |
12 |
13 | get('themeManager')->getItems() as $name => $theme) : ?> 14 | label, ['change-theme', 'theme' => $name], ['class' => 'btn btn-default']) ?>  15 | 16 |
17 |
18 | render('//settings/_form', ['model' => $model]); ?> 19 |
20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /src/storage/SettingsStorageInterface.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class NavbarMenu extends \hiqdev\yii2\menus\Menu 20 | { 21 | public function items() 22 | { 23 | return [ 24 | 'nav' => [ 25 | 'label' => AbstractMainMenu::widget([], [ 26 | 'class' => Nav::class, 27 | 'options' => ['class' => 'nav navbar-nav navbar-right'], 28 | ]), 29 | ], 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/assets/faq/js/faq.min.js: -------------------------------------------------------------------------------- 1 | !function(t,i,o,n){function e(i,o){this.element=t(i),this.items={},this.settings=t.extend({},s,o),this._defaults=s,this._name=a,this.init()}var a="faq",s={} 2 | e.prototype={init:function(){var o=i.location.hash 3 | o&&t('ul a[href="'+o+'"]').tab("show"),t(".faq-categories ul li a").click(function(o){t(this).tab("show") 4 | var n=t("body").scrollTop()||t("html").scrollTop() 5 | i.location.hash=this.hash,t("html,body").scrollTop(n)}),t('.panel-body-content a[href^="#"]').click(function(i){i.preventDefault() 6 | var o=[],n=this.getAttribute("href") 7 | t(n).parents(".collapse").each(function(i,n){o.push(n.getAttribute("id")),t(n).collapse("show")}),t(n).collapse("show") 8 | var e=t(n).offset().top 9 | return t("html, body").animate({scrollTop:e-100},600),!1})}},t.fn[a]=function(i){return t(this).data("plugin_"+a)||t(this).data("plugin_"+a,new e(this,i)),t(this).data("plugin_"+a)}}(jQuery,window,document) 10 | -------------------------------------------------------------------------------- /src/widgets/CopyrightYears.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class CopyrightYears extends \yii\base\Widget 18 | { 19 | /** 20 | * @var string copyright years 21 | */ 22 | public $years; 23 | 24 | /** 25 | * @var string copyright year 26 | */ 27 | public $year; 28 | 29 | public function run() 30 | { 31 | if ($this->years) { 32 | return $this->years; 33 | } 34 | $curr = date('Y'); 35 | 36 | return $this->year ? "{$this->year}-$curr" : $curr; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/widgets/UserMenu.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class UserMenu extends \yii\base\Widget 20 | { 21 | public $options = []; 22 | 23 | public $items = []; 24 | 25 | public function run() 26 | { 27 | return $this->render('UserMenu', [ 28 | 'header' => ArrayHelper::remove($this->items, 'header'), 29 | 'logout' => ArrayHelper::remove($this->items, 'logout'), 30 | 'profile' => ArrayHelper::remove($this->items, 'profile'), 31 | 'items' => $this->items, 32 | 'options' => $this->options, 33 | ]); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/storage/SessionSettingsStorage.php: -------------------------------------------------------------------------------- 1 | toArray(); 30 | Yii::$app->session->set($this->sessionKey, $data); 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function get() 37 | { 38 | return Yii::$app->session->get($this->sessionKey); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/GetManagerTrait.php: -------------------------------------------------------------------------------- 1 | _manager = $manager; 28 | } 29 | 30 | /** 31 | * Getter for manager. 32 | * 33 | * @return ThemeManager 34 | */ 35 | public function getManager() 36 | { 37 | if (!is_object($this->_manager)) { 38 | $this->_manager = Yii::$app->get($this->_manager); 39 | } 40 | 41 | return $this->_manager; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/menus/AbstractMenu.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | abstract class AbstractMenu implements MenuInterface 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public static function widget($menuConfig = [], $widgetConfig = []) 26 | { 27 | return static::create($menuConfig)->run($widgetConfig); 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public static function create($config = []) 34 | { 35 | $config['class'] = get_called_class(); 36 | 37 | return Yii::createObject($config); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | abstract public function run($config = []); 44 | } 45 | -------------------------------------------------------------------------------- /attic/AssetConverter.php: -------------------------------------------------------------------------------- 1 | commands = array_merge([ 23 | 'php' => ['css', 'render'], 24 | ], $this->commands); 25 | } 26 | 27 | /** 28 | * {@inheritdoc} 29 | */ 30 | protected function runCommand($command, $basePath, $asset, $result) 31 | { 32 | if ($command === 'render') { 33 | $res = Yii::$app->getView()->renderFile("$basePath/$asset"); 34 | file_put_contents("$basePath/$result", $res); 35 | } else { 36 | return parent::runCommand($command, $basePath, $asset, $result); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/readme/Configuration.md: -------------------------------------------------------------------------------- 1 | This extension is supposed to be used with [composer-config-plugin]. 2 | 3 | Also you can use it usual way by copy-pasting config. 4 | See [src/config/web.php] for configuration example. 5 | 6 | Available configuration parameters: 7 | 8 | - `themeManager.defaultTheme` - default theme 9 | - `copyright.year` - **CopyrightYears** widget 10 | - `copyright.years` 11 | - `logo.url` - **LogoLink** widget 12 | - `logo.name` 13 | - `logo.options` 14 | - `logo.image` 15 | - `logo.imageOptions` 16 | - `logo.smallImage` 17 | - `logo.smallImageOptions` 18 | - `organization.url` - **OrganizationLink** widget 19 | - `organization.name` 20 | - `organization.options` 21 | - `poweredBy.url` - **PoweredBy** widget 22 | - `poweredBy.name` 23 | - `poweredBy.version` 24 | - `poweredBy.options` 25 | - `socialLinks.links` - **SocialLinks** widget 26 | 27 | For more details please see [src/config/params.php]. 28 | 29 | [composer-config-plugin]: https://github.com/hiqdev/composer-config-plugin 30 | [src/config/params.php]: src/config/params.php 31 | [src/config/web.php]: src/config/web.php 32 | -------------------------------------------------------------------------------- /src/widgets/FancyPanel.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class FancyPanel extends Widget 21 | { 22 | public $panelClass = 'contactmethod'; 23 | 24 | /** 25 | * Example: darkgray|blue|green|purple. 26 | * 27 | * @var string 28 | */ 29 | public $color = 'darkgray'; 30 | 31 | public $title; 32 | 33 | public $content; 34 | 35 | public function init() 36 | { 37 | ob_start(); 38 | ob_implicit_flush(false); 39 | } 40 | 41 | public function run() 42 | { 43 | $this->content = ob_get_clean(); 44 | 45 | return $this->render('FancyPanel', ArrayHelper::toArray($this)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/widgets/OrganizationLink.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class OrganizationLink extends Widget 21 | { 22 | /** 23 | * @var string|array url to organization 24 | */ 25 | public $url; 26 | 27 | /** 28 | * @var string name to display 29 | */ 30 | public $name; 31 | 32 | /** 33 | * @var array html options 34 | */ 35 | public $options = []; 36 | 37 | public function run() 38 | { 39 | return $this->render('OrganizationLink', [ 40 | 'url' => $this->url, 41 | 'name' => $this->name ?: 'Organization', 42 | 'options' => $this->options, 43 | ]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/readme/Idea.md: -------------------------------------------------------------------------------- 1 | The main goal of this theming library is to allow creation and use of easy 2 | pluggable themes: to change a theme on a site it is enough just to require 3 | other theme package in project's `composer.json`. 4 | 5 | To achieve this goal several technologies were used: 6 | 7 | - [Yii2 theming] with `pathMap` auto assembling; 8 | - [Yii2 dependency injection] for widgets and menus; 9 | - [composer-config-plugin] to create themes as plugins i.e. code combined and distributed 10 | together with configuration. 11 | 12 | This package provides: 13 | 14 | - bootrstrappable `ThemeManager` component that collects and setups in application view 15 | proper `Theme` object with proper `pathMap`; 16 | - widgets and menus that can be configured through params and substituted with DI; 17 | - theme `DebugPanel` showing actual `pathMap`. 18 | 19 | [composer-config-plugin]: https://github.com/hiqdev/composer-config-plugin 20 | [yii2 dependency injection]: http://www.yiiframework.com/doc-2.0/guide-concept-di-container.html 21 | [yii2 theming]: http://www.yiiframework.com/doc-2.0/guide-output-theming.html 22 | -------------------------------------------------------------------------------- /config/params.php: -------------------------------------------------------------------------------- 1 | null, 13 | 14 | 'poweredBy.url' => null, 15 | 'poweredBy.name' => null, 16 | 'poweredBy.version' => null, 17 | 'poweredBy.options' => null, 18 | 19 | 'socialLinks.links' => [], 20 | 21 | 'copyright.year' => null, 22 | 'copyright.years' => null, 23 | 24 | 'organization.url' => null, 25 | 'organization.name' => null, 26 | 'organization.options' => null, 27 | 28 | 'logo.url' => null, 29 | 'logo.name' => null, 30 | 'logo.options' => null, 31 | 'logo.image' => null, 32 | 'logo.imageOptions' => null, 33 | 'logo.smallImage' => null, 34 | 'logo.smallImageOptions' => null, 35 | ]; 36 | -------------------------------------------------------------------------------- /src/DetailedTheme.php: -------------------------------------------------------------------------------- 1 | theme = $theme; 38 | } 39 | 40 | public function getAttributes() 41 | { 42 | return array_merge(ArrayHelper::toArray($this->theme), ArrayHelper::toArray($this)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/menus/MenuInterface.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | interface MenuInterface 19 | { 20 | /** 21 | * Creates menu object with given config. 22 | * @param mixed $config 23 | * @return MenuInterface 24 | */ 25 | public static function create($config = []); 26 | 27 | /** 28 | * Creates menu and renders with given configs. 29 | * @param mixed $menuConfig 30 | * @param mixed $widgetConfig 31 | * @return string rendered menu 32 | */ 33 | public static function widget($menuConfig = [], $widgetConfig = []); 34 | 35 | /** 36 | * Renders menu with given widget config. 37 | * @param mixed $config widget config 38 | * @return string rendered menu 39 | */ 40 | public function run($config = []); 41 | } 42 | -------------------------------------------------------------------------------- /src/widgets/PoweredBy.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class PoweredBy extends Widget 20 | { 21 | /** 22 | * @var string|array url to empowerer 23 | */ 24 | public $url; 25 | 26 | /** 27 | * @var string name to display 28 | */ 29 | public $name; 30 | 31 | /** 32 | * @var string version to display if given 33 | */ 34 | public $version; 35 | 36 | /** 37 | * @var array html options 38 | */ 39 | public $options = []; 40 | 41 | public function run() 42 | { 43 | return $this->render('PoweredBy', [ 44 | 'url' => $this->url, 45 | 'name' => $this->name, 46 | 'version' => $this->version, 47 | 'options' => $this->options, 48 | ]); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /chkipper.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hiqdev/yii2-thememanager", 3 | "authors": { 4 | "hiqsol": { 5 | "name": "Andrii Vasyliev", 6 | "role": "Project lead", 7 | "email": "sol@hiqdev.com", 8 | "github": "https://github.com/hiqsol", 9 | "homepage": "http://hipanel.com/" 10 | }, 11 | "SilverFire": { 12 | "name": "Dmitry Naumenko", 13 | "role": "Lead backend developer", 14 | "email": "d.naumenko.a@gmail.com", 15 | "github": "https://github.com/SilverFire", 16 | "homepage": "http://silverfire.me/" 17 | }, 18 | "tafid": { 19 | "name": "Andrey Klochok", 20 | "role": "Lead frontend developer", 21 | "email": "andreyklochok@gmail.com", 22 | "github": "https://github.com/tafid", 23 | "homepage": "http://hiqdev.com/" 24 | }, 25 | "BladeRoot": { 26 | "name": "Yuriy Myronchuk", 27 | "role": "QA Lead", 28 | "email": "bladeroot@gmail.com", 29 | "github": "https://github.com/BladeRoot", 30 | "homepage": "http://hiqdev.com/" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /attic/AssetManager.php: -------------------------------------------------------------------------------- 1 | _ac === null) { 31 | $this->_ac = Yii::createObject(AssetConverter::class); 32 | } elseif (is_array($this->_ac) || is_string($this->_ac)) { 33 | if (is_array($this->_ac) && !isset($this->_ac['class'])) { 34 | $this->_ac['class'] = AssetConverter::class; 35 | } 36 | $this->_ac = Yii::createObject($this->_ac); 37 | } 38 | 39 | return $this->_ac; 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function setConverter($value) 46 | { 47 | $this->_ac = $value; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/widgets/Markdown.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | class Markdown extends Widget 22 | { 23 | /** 24 | * @var array options XXX ? 25 | */ 26 | public $options = []; 27 | 28 | /** 29 | * @var string markdown source to render 30 | */ 31 | public $source; 32 | 33 | /** 34 | * @var string markdown file to render 35 | */ 36 | public $file; 37 | 38 | public function run() 39 | { 40 | $parser = new GithubMarkdown(); 41 | 42 | return $parser->parse($this->prepareSource()); 43 | } 44 | 45 | protected function prepareSource() 46 | { 47 | return $this->source ?: $this->readFile($this->file); 48 | } 49 | 50 | protected function readFile($file) 51 | { 52 | return file_get_contents(Yii::getAlias($file)); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/widgets/views/faq/node.php: -------------------------------------------------------------------------------- 1 | 9 |
10 |
11 |

12 | ' . $item['label'], '#' . $itemId, [ 13 | 'data-toggle' => 'collapse', 14 | 'data-parent' => '#' . $parentId, 15 | ]) ?> 16 |

17 |
18 |
19 |
20 | 21 |
22 |
23 | $subItem) : ?> 24 | render('node', ['item' => $subItem, 'itemId' => $subItemId, 'parentId' => $itemId]) ?> 25 | 26 |
27 |
28 | 29 | 'panel-body-content']) ?> 30 | 31 |
32 |
33 |
34 | -------------------------------------------------------------------------------- /src/widgets/SocialLinks.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class SocialLinks extends \yii\base\Widget 20 | { 21 | public $tag = 'li'; 22 | 23 | public $tagOptions = []; 24 | 25 | public $links = []; 26 | 27 | public $linkOptions = []; 28 | 29 | public $icons = [ 30 | 'github' => 'github-alt', 31 | 'email' => 'envelope', 32 | ]; 33 | 34 | public function run() 35 | { 36 | $out = ''; 37 | foreach ($this->links as $name => $value) { 38 | if ($value) { 39 | $icon = isset($this->icons[$name]) ? $this->icons[$name] : $name; 40 | $out .= Html::beginTag($this->tag, $this->tagOptions); 41 | $out .= Html::a(Html::tag('span', '', ['class' => "fa fa-{$icon}"]), $value, array_merge(['title' => ucfirst($name)], $this->linkOptions)); 42 | $out .= Html::endTag($this->tag); 43 | } 44 | } 45 | 46 | return $out; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/messages/ru/hiqdev.thememanager.php: -------------------------------------------------------------------------------- 1 | 'Я уже зарегистрирован', 30 | 'I forgot my password' => 'Я забыл пароль', 31 | 'Powered by' => 'Powered by', 32 | 'Register a new membership' => 'Зарегистрироваться', 33 | 'Theme Settings' => 'Настройки темы', 34 | 'version' => 'версия', 35 | 'Layout settings saved' => 'Настройки верстки сохранены', 36 | 'Theme changed' => 'Тема изменена', 37 | ]; 38 | -------------------------------------------------------------------------------- /src/widgets/TextPage.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class TextPage extends \yii\base\Widget 18 | { 19 | protected $header; 20 | 21 | protected $footer; 22 | 23 | public function init() 24 | { 25 | $this->start(); 26 | } 27 | 28 | public function run() 29 | { 30 | return $this->render('TextPage', [ 31 | 'content' => $this->finish(), 32 | 'header' => $this->header, 33 | 'footer' => $this->footer, 34 | ]); 35 | } 36 | 37 | public function beginHeader() 38 | { 39 | $this->start(); 40 | } 41 | 42 | public function endHeader() 43 | { 44 | $this->header = $this->finish(); 45 | } 46 | 47 | public function beginFooter() 48 | { 49 | $this->start(); 50 | } 51 | 52 | public function endFooter() 53 | { 54 | $this->footer = $this->finish(); 55 | } 56 | 57 | protected function start() 58 | { 59 | ob_start(); 60 | ob_implicit_flush(false); 61 | } 62 | 63 | protected function finish() 64 | { 65 | return ob_get_clean(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2015-2017, HiQDev (http://hiqdev.com/) 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of HiQDev nor the names of its 15 | contributors may be used to endorse or promote products derived 16 | from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /src/widgets/views/faq/root.php: -------------------------------------------------------------------------------- 1 | 8 |
9 |
10 |
11 |
12 |
    13 | $tab): ?> 14 |
  • 15 | %d', $tab['label'], count($tab['items'])), '#tab-' . $tabId, ['data-toggle' => 'tab']) ?> 16 |
  • 17 | 18 |
19 |
20 |
21 |
22 |
23 | 24 |
25 |
26 |
27 |
28 |
29 | $tab) : ?> 30 |
31 |
32 | $item) : ?> 33 | render('node', ['item' => $item, 'itemId' => $itemId, 'parentId' => $tabId]) ?> 34 | 35 |
36 |
37 | 38 |
39 |
40 |
41 |
42 |
-------------------------------------------------------------------------------- /src/widgets/views/LoginForm.php: -------------------------------------------------------------------------------- 1 | 11 |
12 |

title) ?>

13 | 14 |

Please fill out the following fields to login:

15 | 16 | 'login-form', 18 | 'options' => ['class' => 'form-horizontal'], 19 | 'fieldConfig' => [ 20 | 'template' => "{label}\n
{input}
\n
{error}
", 21 | 'labelOptions' => ['class' => 'col-lg-1 control-label'], 22 | ], 23 | ]); ?> 24 | 25 | field($model, 'username')->textInput(['autofocus' => true]) ?> 26 | 27 | field($model, 'password')->passwordInput() ?> 28 | 29 | field($model, 'rememberMe')->checkbox([ 30 | 'template' => "
{input} {label}
\n
{error}
", 31 | ]) ?> 32 | 33 |
34 |
35 | 'btn btn-primary', 'name' => 'login-button']) ?> 36 |
37 |
38 | 39 | 40 | 41 |
42 | You may login with admin/admin or demo/demo.
43 | To modify the username/password, please check out the code app\models\User::$users. 44 |
45 |
46 | -------------------------------------------------------------------------------- /src/views/debug/detail.php: -------------------------------------------------------------------------------- 1 | 8 |

Themes

9 | 10 | data)) { 11 | echo '

No theme was used.

'; 12 | 13 | return; 14 | } ?> 15 |
16 | 17 | 24 | getThemes() as $name => $theme) : ?> 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
18 |

19 | Total getCount() ?> themes were defined. 20 | Current: getCurrent() ?>. 21 | Default: getDefault() ?>. 22 |

23 |

50 |
51 | -------------------------------------------------------------------------------- /src/models/Settings.php: -------------------------------------------------------------------------------- 1 | _defaults as $k => $v) { 36 | if (is_null($this->$k)) { 37 | $this->$k = $v; 38 | } 39 | } 40 | 41 | return true; 42 | } 43 | 44 | /** 45 | * Default css provider - returns plain value, fits for attributes like skin and layout. 46 | * @param $name string attribute name 47 | * @param $value boolean|string attribute value 48 | * @return string css class 49 | */ 50 | public static function cssClassProvider($name, $value) 51 | { 52 | return $value; 53 | } 54 | 55 | public function getCssClass($name) 56 | { 57 | return static::cssClassProvider($name, $this->$name); 58 | } 59 | 60 | public function getCssClasses(array $names) 61 | { 62 | $classes = []; 63 | 64 | foreach ($names as $n) { 65 | $classes[$n] = $this->getCssClass($n); 66 | } 67 | 68 | return implode(' ', array_filter($classes)); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /hidev.yml: -------------------------------------------------------------------------------- 1 | package: 2 | type: yii2-extension 3 | name: yii2-thememanager 4 | title: Pluggable themes for Yii2 5 | headline: Yii2 Theme Manager 6 | keywords: yii2, theme, manager 7 | description: | 8 | This [Yii2] plugin provides easy theming for Yii2 projects. 9 | And allows to create and use themes as composer packages. 10 | So changing a theme on a site becomes as simple as changing 11 | a single require line in `composer.json`. 12 | 13 | At the moment there are several themes available: 14 | 15 | - AdminLte - [yii2-theme-adminlte] 16 | - Agency - [yii2-theme-agency] 17 | - DataServ - [yii2-theme-dataserv] 18 | - Flat - [yii2-theme-flat] 19 | - Hyde - [yii2-theme-hyde] 20 | - Obaju - [yii2-theme-obaju] 21 | - Yii2 original - [yii2-theme-original] 22 | - Sailor - [yii2-theme-sailor] 23 | - Twenty Fifteen - [yii2-theme-twentyfifteen] 24 | 25 | [yii2]: http://www.yiiframework.com/ 26 | [yii2-theme-adminlte]: https://github.com/hiqdev/yii2-theme-adminlte 27 | [yii2-theme-agency]: https://github.com/hiqdev/yii2-theme-agency 28 | [yii2-theme-dataserv]: https://github.com/hiqdev/yii2-theme-dataserv 29 | [yii2-theme-flat]: https://github.com/hiqdev/yii2-theme-flat 30 | [yii2-theme-hyde]: https://github.com/hiqdev/yii2-theme-hyde 31 | [yii2-theme-obaju]: https://github.com/hiqdev/yii2-theme-obaju 32 | [yii2-theme-original]: https://github.com/hiqdev/yii2-theme-original 33 | [yii2-theme-sailor]: https://github.com/hiqdev/yii2-theme-sailor 34 | [yii2-theme-twentyfifteen]: https://github.com/hiqdev/yii2-theme-twentyfifteen 35 | -------------------------------------------------------------------------------- /src/assets/faq/js/faq.js: -------------------------------------------------------------------------------- 1 | ;(function ($, window, document, undefined) { 2 | var pluginName = "faq"; 3 | var defaults = {}; 4 | 5 | function Plugin(element, options) { 6 | var _this = this; 7 | this.element = $(element); 8 | this.items = {}; 9 | this.settings = $.extend({}, defaults, options); 10 | this._defaults = defaults; 11 | this._name = pluginName; 12 | this.init(); 13 | } 14 | 15 | Plugin.prototype = { 16 | init: function () { 17 | var _this = this; 18 | var hash = window.location.hash; 19 | hash && $('ul a[href=\"' + hash + '\"]').tab('show'); 20 | $('.faq-categories ul li a').click(function (e) { 21 | $(this).tab('show'); 22 | var scrollmem = $('body').scrollTop() || $('html').scrollTop(); 23 | window.location.hash = this.hash; 24 | $('html,body').scrollTop(scrollmem); 25 | }); 26 | $('.panel-body-content a[href^="#"]').click(function (e) { 27 | e.preventDefault(); 28 | var el = []; 29 | var id = this.getAttribute('href'); 30 | $(id).parents('.collapse').each(function (i, elem) { 31 | el.push(elem.getAttribute('id')); 32 | $(elem).collapse('show'); 33 | }); 34 | $(id).collapse('show'); 35 | var scrl = $(id).offset().top; 36 | $('html, body').animate({ 37 | scrollTop: scrl - 100 38 | }, 600); 39 | 40 | return false; 41 | }); 42 | } 43 | }; 44 | 45 | $.fn[pluginName] = function (options) { 46 | if (!$(this).data("plugin_" + pluginName)) { 47 | $(this).data("plugin_" + pluginName, new Plugin(this, options)); 48 | } 49 | 50 | return $(this).data("plugin_" + pluginName); 51 | }; 52 | })(jQuery, window, document); 53 | -------------------------------------------------------------------------------- /src/widgets/LogoLink.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | class LogoLink extends Widget 22 | { 23 | /** 24 | * @var array html options 25 | */ 26 | public $options = []; 27 | 28 | /** 29 | * @var string url to image 30 | */ 31 | public $image; 32 | 33 | /** 34 | * @var string text to display 35 | */ 36 | public $name; 37 | 38 | /** 39 | * @var array|string text to display 40 | */ 41 | public $url; 42 | 43 | public $smallImage; 44 | 45 | public $imageOptions = []; 46 | 47 | public $smallImageOptions = []; 48 | 49 | public function run() 50 | { 51 | return $this->render('LogoLink', $this->collectData()); 52 | } 53 | 54 | protected function collectData() 55 | { 56 | $data = [ 57 | 'name' => $this->name, 58 | 'url' => $this->url, 59 | 'options' => $this->options, 60 | ]; 61 | if ($this->smallImage) { 62 | $data['smallImage'] = $this->getImage($this->smallImage); 63 | $data['smallImageOptions'] = $this->smallImageOptions; 64 | } 65 | if ($this->image) { 66 | $data['image'] = $this->getImage($this->image); 67 | $data['imageOptions'] = $this->imageOptions; 68 | } 69 | 70 | return $data; 71 | } 72 | 73 | protected function getImage($path) 74 | { 75 | return Url::to( 76 | mb_substr($path, 0, 1, 'utf-8') === '@' 77 | ? Yii::$app->assetManager->publish($path)[1] 78 | : $path, 79 | true, 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /attic/View.php: -------------------------------------------------------------------------------- 1 | getManager()->getSettings()->getBodyClasses(); 23 | } 24 | 25 | /** 26 | * Magic setter. 27 | * 28 | * @param int|string $name 29 | * @param mixed $value the element value 30 | */ 31 | public function __set($name, $value) 32 | { 33 | if ($name && $this->canSetProperty($name)) { 34 | parent::__set($name, $value); 35 | } else { 36 | $this->params[$name] = $value; 37 | } 38 | } 39 | 40 | /** 41 | * Magic getter. 42 | * 43 | * @param string $name component or property name 44 | * 45 | * @return mixed param or property value 46 | */ 47 | public function __get($name) 48 | { 49 | if ($name && $this->canGetProperty($name)) { 50 | return parent::__get($name); 51 | } else { 52 | return $this->params[$name]; 53 | } 54 | } 55 | 56 | /** 57 | * Magic is set checker. 58 | * 59 | * @param string $name the property or param name to check 60 | * 61 | * @return bool whether the value is set 62 | */ 63 | public function __isset($name) 64 | { 65 | return ($name && parent::__isset($name)) || isset($this->params[$name]); 66 | } 67 | 68 | /** 69 | * Magic unsetter. 70 | * 71 | * @param string $name the property or param name to unset 72 | */ 73 | public function __unset($name) 74 | { 75 | if ($name && $this->canSetProperty($name)) { 76 | parent::__unset($name); 77 | } else { 78 | unset($this->params[$name]); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hiqdev/yii2-thememanager", 3 | "type": "yii2-extension", 4 | "description": "Pluggable themes for Yii2", 5 | "keywords": [ 6 | "yii2", 7 | "theme", 8 | "manager" 9 | ], 10 | "homepage": "https://github.com/hiqdev/yii2-thememanager", 11 | "license": "BSD-3-Clause", 12 | "support": { 13 | "email": "support@hiqdev.com", 14 | "source": "https://github.com/hiqdev/yii2-thememanager", 15 | "issues": "https://github.com/hiqdev/yii2-thememanager/issues", 16 | "wiki": "https://github.com/hiqdev/yii2-thememanager/wiki", 17 | "forum": "http://forum.hiqdev.com/" 18 | }, 19 | "authors": [ 20 | { 21 | "name": "Andrii Vasyliev", 22 | "role": "Project lead", 23 | "email": "sol@hiqdev.com", 24 | "homepage": "http://hipanel.com/" 25 | }, 26 | { 27 | "name": "Dmitry Naumenko", 28 | "role": "Lead backend developer", 29 | "email": "d.naumenko.a@gmail.com", 30 | "homepage": "http://silverfire.me/" 31 | }, 32 | { 33 | "name": "Andrey Klochok", 34 | "role": "Lead frontend developer", 35 | "email": "andreyklochok@gmail.com", 36 | "homepage": "http://hiqdev.com/" 37 | }, 38 | { 39 | "name": "Yuriy Myronchuk", 40 | "role": "QA Lead", 41 | "email": "bladeroot@gmail.com", 42 | "homepage": "http://hiqdev.com/" 43 | } 44 | ], 45 | "require": { 46 | "hiqdev/yii2-collection": "*" 47 | }, 48 | "require-dev": { 49 | "hiqdev/hidev-php": "<2.0", 50 | "hiqdev/hidev-hiqdev": "<2.0" 51 | }, 52 | "autoload": { 53 | "psr-4": { 54 | "hiqdev\\thememanager\\": "src" 55 | } 56 | }, 57 | "extra": { 58 | "config-plugin": { 59 | "params": "config/params.php", 60 | "web": "config/web.php" 61 | } 62 | }, 63 | "repositories": [ 64 | { 65 | "type": "composer", 66 | "url": "https://asset-packagist.org" 67 | } 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | setUsingCache(true) 14 | ->setRiskyAllowed(true) 15 | ->setRules(array( 16 | '@Symfony' => true, 17 | 'header_comment' => [ 18 | 'header' => $header, 19 | 'separate' => 'bottom', 20 | 'location' => 'after_declare_strict', 21 | 'commentType' => 'PHPDoc', 22 | ], 23 | 'binary_operator_spaces' => [ 24 | 'default' => null, 25 | ], 26 | 'concat_space' => ['spacing' => 'one'], 27 | 'array_syntax' => ['syntax' => 'short'], 28 | 'phpdoc_no_alias_tag' => ['replacements' => ['type' => 'var']], 29 | 'blank_line_before_return' => false, 30 | 'phpdoc_align' => false, 31 | 'phpdoc_scalar' => false, 32 | 'phpdoc_separation' => false, 33 | 'phpdoc_to_comment' => false, 34 | 'method_argument_space' => false, 35 | 'ereg_to_preg' => true, 36 | 'blank_line_after_opening_tag' => true, 37 | 'single_blank_line_before_namespace' => true, 38 | 'ordered_imports' => true, 39 | 'phpdoc_order' => true, 40 | 'pre_increment' => true, 41 | 'strict_comparison' => true, 42 | 'strict_param' => true, 43 | 'no_multiline_whitespace_before_semicolons' => true, 44 | 'semicolon_after_instruction' => false, 45 | 'yoda_style' => false, 46 | )) 47 | ->setFinder( 48 | PhpCsFixer\Finder::create() 49 | ->in(__DIR__) 50 | ->notPath('vendor') 51 | ->notPath('runtime') 52 | ->notPath('web/assets') 53 | ) 54 | ; 55 | -------------------------------------------------------------------------------- /src/debug/Panel.php: -------------------------------------------------------------------------------- 1 | _viewPath = $value; 26 | } 27 | 28 | public function getViewPath() 29 | { 30 | if ($this->_viewPath === null) { 31 | $this->_viewPath = dirname(__DIR__) . '/views/debug'; 32 | } 33 | 34 | return $this->_viewPath; 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function getName() 41 | { 42 | return 'Themes'; 43 | } 44 | 45 | /** 46 | * {@inheritdoc} 47 | */ 48 | public function getSummary() 49 | { 50 | return Yii::$app->view->render('summary', ['panel' => $this], $this); 51 | } 52 | 53 | /** 54 | * {@inheritdoc} 55 | */ 56 | public function getDetail() 57 | { 58 | return Yii::$app->view->render('detail', ['panel' => $this], $this); 59 | } 60 | 61 | public function getThemes() 62 | { 63 | return isset($this->data['themes']) ? $this->data['themes'] : []; 64 | } 65 | 66 | public function getCount() 67 | { 68 | return count($this->getThemes()); 69 | } 70 | 71 | public function getCurrent() 72 | { 73 | return isset($this->data['current']) ? $this->data['current'] : ''; 74 | } 75 | 76 | public function getDefault() 77 | { 78 | return isset($this->data['default']) ? $this->data['default'] : ''; 79 | } 80 | 81 | /** 82 | * {@inheritdoc} 83 | */ 84 | public function save() 85 | { 86 | $manager = $this->getManager(); 87 | $items = $manager->getItems(); 88 | $themes = ArrayHelper::toArray($items); 89 | foreach ($items as $name => $theme) { 90 | $themes[$name]['class'] = get_class($theme); 91 | } 92 | 93 | return [ 94 | 'themes' => $themes, 95 | 'current' => $manager->getTheme()->name ?? '', 96 | 'default' => $manager->getDefaultTheme(), 97 | ]; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /config/web.php: -------------------------------------------------------------------------------- 1 | ['themeManager' => 'themeManager'], 13 | 'components' => [ 14 | 'themeSettingsStorage' => [ 15 | 'class' => \hiqdev\thememanager\storage\SessionSettingsStorage::class, 16 | ], 17 | 'themeManager' => array_filter([ 18 | 'class' => \hiqdev\thememanager\ThemeManager::class, 19 | 'defaultTheme' => $params['themeManager.defaultTheme'], 20 | ]), 21 | 'i18n' => [ 22 | 'translations' => [ 23 | 'hiqdev.thememanager' => [ 24 | 'class' => \yii\i18n\PhpMessageSource::class, 25 | 'basePath' => dirname(__DIR__) . '/src/messages', 26 | ], 27 | ], 28 | ], 29 | ], 30 | 'modules' => array_filter([ 31 | 'thememanager' => [ 32 | 'class' => \hiqdev\thememanager\Module::class, 33 | 'defaultRoute' => 'settings', 34 | ], 35 | 'debug' => empty($params['debug.enabled']) ? null : [ 36 | 'panels' => [ 37 | 'themes' => [ 38 | 'class' => \hiqdev\thememanager\debug\Panel::class, 39 | ], 40 | ], 41 | ], 42 | ]), 43 | 'container' => [ 44 | 'singletons' => [ 45 | \hiqdev\thememanager\menus\AbstractNavbarMenu::class => [ 46 | 'class' => \hiqdev\thememanager\menus\NavbarMenu::class, 47 | ], 48 | ], 49 | 'definitions' => [ 50 | \hiqdev\thememanager\widgets\PoweredBy::class => array_filter([ 51 | 'url' => $params['poweredBy.url'], 52 | 'name' => $params['poweredBy.name'], 53 | 'version' => $params['poweredBy.version'], 54 | 'options' => $params['poweredBy.options'], 55 | ]), 56 | \hiqdev\thememanager\widgets\SocialLinks::class => array_filter([ 57 | 'links' => $params['socialLinks.links'], 58 | ]), 59 | \hiqdev\thememanager\widgets\CopyrightYears::class => array_filter([ 60 | 'year' => $params['copyright.year'], 61 | 'years' => $params['copyright.years'], 62 | ]), 63 | \hiqdev\thememanager\widgets\OrganizationLink::class => array_filter([ 64 | 'url' => $params['organization.url'], 65 | 'name' => $params['organization.name'], 66 | 'options' => $params['organization.options'], 67 | ]), 68 | \hiqdev\thememanager\widgets\LogoLink::class => array_filter([ 69 | 'url' => $params['logo.url'] ?: '/', 70 | 'name' => $params['logo.name'] ?: $params['organization.name'] ?: 'Logo', 71 | 'options' => $params['logo.options'], 72 | 'image' => $params['logo.image'], 73 | 'imageOptions' => $params['logo.imageOptions'], 74 | 'smallImage' => $params['logo.smallImage'], 75 | 'smallImageOptions' => $params['logo.smallImageOptions'], 76 | ]), 77 | ], 78 | ], 79 | ]; 80 | -------------------------------------------------------------------------------- /src/controllers/SettingsController.php: -------------------------------------------------------------------------------- 1 | module->getManager()->getSettings(); 33 | } 34 | 35 | /** 36 | * @return SettingsStorageInterface 37 | */ 38 | public function getThemeSettingsStorage() 39 | { 40 | return Yii::$app->get('themeSettingsStorage'); 41 | } 42 | 43 | public function getUiOptionsStorage() 44 | { 45 | return Yii::$app->get('uiOptionsStorage'); 46 | } 47 | 48 | /** 49 | * Settings form. 50 | * 51 | * @return string|Response 52 | */ 53 | public function actionIndex() 54 | { 55 | $model = $this->getModel(); 56 | 57 | $data = Yii::$app->request->post($model->formName()); 58 | if (empty($data)) { 59 | $data = $this->getThemeSettingsStorage()->get(); 60 | } 61 | 62 | if (Yii::$app->request->getIsPost() && $model->load($data) && $model->validate()) { 63 | $this->getThemeSettingsStorage()->set($model); 64 | $this->setGlobalOrientation($model->filterOrientation); 65 | Yii::$app->session->setFlash('success', Yii::t('hiqdev.thememanager', 'Layout settings saved.')); 66 | } 67 | 68 | if (Yii::$app->request->isAjax) { 69 | return $this->renderAjax('//settings/_form', compact('model')); 70 | } 71 | 72 | return $this->render('index', compact('model')); 73 | } 74 | 75 | /** 76 | * @param null $orientation 77 | */ 78 | public function setGlobalOrientation($orientation = null) 79 | { 80 | if ($orientation !== null) { 81 | $settings = $this->getUiOptionsStorage()->getAllUiOptions(); 82 | foreach ($settings as $route => $data) { 83 | $model = new IndexPageUiOptions($data); 84 | $model->orientation = $orientation; 85 | if ($model->validate()) { 86 | $this->getUiOptionsStorage()->set($route, $model->toArray()); 87 | } else { 88 | Yii::warning('SettingsController - IndexPageUiModel validation errors: ' . json_encode($model->getErrors())); 89 | } 90 | } 91 | } 92 | } 93 | 94 | /** 95 | * @param $theme 96 | * @return Response 97 | */ 98 | public function actionChangeTheme($theme) 99 | { 100 | if ($this->module->getManager()->has($theme)) { 101 | $model = $this->getModel(); 102 | $model->theme = $theme; 103 | $this->getThemeSettingsStorage()->set($model); 104 | Yii::$app->session->setFlash('success', Yii::t('hiqdev.thememanager', 'Theme changed')); 105 | } 106 | 107 | return $this->redirect(['index']); 108 | } 109 | 110 | public function actionCollapsedSidebar() 111 | { 112 | if (Yii::$app->request->isAjax) { 113 | $model = $this->getModel(); 114 | $model->collapsed_sidebar = Yii::$app->request->post('collapsed_sidebar'); 115 | $this->getThemeSettingsStorage()->set($model); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # hiqdev/yii2-thememanager 2 | 3 | ## [0.4.1] - 2022-06-29 4 | 5 | - ThemeManager have to set View::theme before render ([@SilverFire]) 6 | 7 | ## [0.4.0] - 2022-06-29 8 | 9 | - Do not initialize a session connect unless required ([@SilverFire]) 10 | - Added `AlertWidget` ([@tafid], [@SilverFire]) 11 | - LoginForm::getBoolAttributes() will be retrun scenario active only ([@tafid]) 12 | - Other minor changes ([smy980807@ukr.net], [@hiqsol], [@SilverFire]) 13 | 14 | ## [0.3.2] - 2022-06-29 15 | 16 | - Fixed minor issues ([@hiqsol], [@tafid]) 17 | - Added `NavbarMenu` ([@hiqsol]) 18 | - Moved theme tuning views to `src/views/themes` <- src/themes ([@hiqsol]) 19 | - Improved docs ([@hiqsol]) 20 | - Added `Markdown` widget ([@hiqsol]) 21 | - Fixed configs ([@hiqsol]) 22 | 23 | ## [0.3.1] - 2022-06-29 24 | 25 | - Renamed poweredBy params to dot style ([@hiqsol]) 26 | - Added `OrientationInterface` ([@tafid]) 27 | - Added `themeManager.defaultTheme` parameter ([@hiqsol]) 28 | - Added Faq, FancyPanel widgets ([@tafid]) 29 | - Added in-site theming ([@hiqsol]) 30 | - Added LogoLink widget ([@tafid], [@hiqsol]) 31 | - Added `DetailedTheme` class ([@tafid]) 32 | 33 | ## [0.3.0] - 2022-06-29 34 | 35 | - Fixed minor issues ([@hiqsol], [@SilverFire], [@tafid]) 36 | - Added Faq and TextPage widgets ([@tafid]) 37 | - Added abstract menus ([@hiqsol]) 38 | - Removed widget, hasWidget and callStatic from ThemeManager, redone creating widgets to straight yii DI ([@hiqsol]) 39 | 40 | ## [0.2.0] - 2022-06-29 41 | 42 | - Added UserMenu, FancyPanel ([@hiqsol], [@tafid], [@SilverFire]) 43 | - Fixed many widgets ([@hiqsol]) 44 | - Added SessionSettingsStorage ([@SilverFire], [@hiqsol]) 45 | - Added Themes debug panel ([@hiqsol]) 46 | - Changed building pathMap ([@hiqsol]) 47 | 48 | ## [0.1.0] - 2022-06-29 49 | 50 | - Changed: redone building theme pathMap with vars substituting ([@hiqsol]) 51 | - Changed: redone widgets to pass params through config ([@hiqsol], [@tafid]) 52 | 53 | ## [0.0.2] - 2022-06-29 54 | 55 | - Added widgets: OrganizationLink, SocialLinks, PoweredBy, LoginForm, Breadcrumbs ([@hiqsol], [@tafid]) 56 | - Added viewPaths parameter ([@hiqsol]) 57 | - Removed View, AssetConverter and AssetManager ([@hiqsol]) 58 | 59 | ## [0.0.1] - 2022-06-29 60 | 61 | - Changed bootstrapping ([@hiqsol]) 62 | - Changed: redone to `composer-config-plugin` ([@hiqsol]) 63 | - Fixed minor issues ([@hiqsol], [@tafid], [@SilverFire]) 64 | - Fixed getting current theme ([@hiqsol]) 65 | - Changed: moved to src ([@hiqsol]) 66 | - Added AssetManager and AssetConverter ([@hiqsol]) 67 | - Added basics ([@hiqsol], [@SilverFire]) 68 | 69 | ## [Development started] - 2022-06-29 70 | 71 | ## [dev] - 2022-06-29 72 | 73 | [@hiqsol]: https://github.com/hiqsol 74 | [sol@hiqdev.com]: https://github.com/hiqsol 75 | [@SilverFire]: https://github.com/SilverFire 76 | [d.naumenko.a@gmail.com]: https://github.com/SilverFire 77 | [@tafid]: https://github.com/tafid 78 | [andreyklochok@gmail.com]: https://github.com/tafid 79 | [@BladeRoot]: https://github.com/BladeRoot 80 | [bladeroot@gmail.com]: https://github.com/BladeRoot 81 | [Under development]: https://github.com/hiqdev/yii2-thememanager/compare/0.3.2...HEAD 82 | [0.2.0]: https://github.com/hiqdev/yii2-thememanager/compare/0.1.0...0.2.0 83 | [0.1.0]: https://github.com/hiqdev/yii2-thememanager/compare/0.0.2...0.1.0 84 | [0.0.2]: https://github.com/hiqdev/yii2-thememanager/compare/0.0.1...0.0.2 85 | [0.0.1]: https://github.com/hiqdev/yii2-thememanager/releases/tag/0.0.1 86 | [0.3.0]: https://github.com/hiqdev/yii2-thememanager/compare/0.2.0...0.3.0 87 | [0.3.1]: https://github.com/hiqdev/yii2-thememanager/compare/0.3.0...0.3.1 88 | [0.3.2]: https://github.com/hiqdev/yii2-thememanager/compare/0.3.1...0.3.2 89 | [Development started]: https://github.com/hiqdev/yii2-thememanager/compare/dev...Development started 90 | [0.4.0]: https://github.com/hiqdev/yii2-thememanager/compare/0.3.2...0.4.0 91 | [0.4.1]: https://github.com/hiqdev/yii2-thememanager/compare/0.4.0...0.4.1 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yii2 Theme Manager 2 | 3 | **Pluggable themes for Yii2** 4 | 5 | [![Latest Stable Version](https://poser.pugx.org/hiqdev/yii2-thememanager/v/stable)](https://packagist.org/packages/hiqdev/yii2-thememanager) 6 | [![Total Downloads](https://poser.pugx.org/hiqdev/yii2-thememanager/downloads)](https://packagist.org/packages/hiqdev/yii2-thememanager) 7 | [![Build Status](https://img.shields.io/travis/hiqdev/yii2-thememanager.svg)](https://travis-ci.org/hiqdev/yii2-thememanager) 8 | [![Scrutinizer Code Coverage](https://img.shields.io/scrutinizer/coverage/g/hiqdev/yii2-thememanager.svg)](https://scrutinizer-ci.com/g/hiqdev/yii2-thememanager/) 9 | [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/hiqdev/yii2-thememanager.svg)](https://scrutinizer-ci.com/g/hiqdev/yii2-thememanager/) 10 | [![Dependency Status](https://www.versioneye.com/php/hiqdev:yii2-thememanager/dev-master/badge.svg)](https://www.versioneye.com/php/hiqdev:yii2-thememanager/dev-master) 11 | 12 | This [Yii2] plugin provides easy theming for Yii2 projects. 13 | And allows to create and use themes as composer packages. 14 | So changing a theme on a site becomes as simple as changing 15 | a single require line in `composer.json`. 16 | 17 | At the moment there are several themes available: 18 | 19 | - AdminLte - [yii2-theme-adminlte] 20 | - Agency - [yii2-theme-agency] 21 | - DataServ - [yii2-theme-dataserv] 22 | - Flat - [yii2-theme-flat] 23 | - Hyde - [yii2-theme-hyde] 24 | - Obaju - [yii2-theme-obaju] 25 | - Yii2 original - [yii2-theme-original] 26 | - Sailor - [yii2-theme-sailor] 27 | - Twenty Fifteen - [yii2-theme-twentyfifteen] 28 | 29 | [yii2]: http://www.yiiframework.com/ 30 | [yii2-theme-adminlte]: https://github.com/hiqdev/yii2-theme-adminlte 31 | [yii2-theme-agency]: https://github.com/hiqdev/yii2-theme-agency 32 | [yii2-theme-dataserv]: https://github.com/hiqdev/yii2-theme-dataserv 33 | [yii2-theme-flat]: https://github.com/hiqdev/yii2-theme-flat 34 | [yii2-theme-hyde]: https://github.com/hiqdev/yii2-theme-hyde 35 | [yii2-theme-obaju]: https://github.com/hiqdev/yii2-theme-obaju 36 | [yii2-theme-original]: https://github.com/hiqdev/yii2-theme-original 37 | [yii2-theme-sailor]: https://github.com/hiqdev/yii2-theme-sailor 38 | [yii2-theme-twentyfifteen]: https://github.com/hiqdev/yii2-theme-twentyfifteen 39 | 40 | ## Installation 41 | 42 | This package is not intended to be required directly in your project. 43 | Instead you should require theme(s) you've chosen and this package 44 | will get required as a dependency. 45 | 46 | Please see [hiqdev/hisite-template] as example of project using this theming 47 | library. 48 | 49 | [hiqdev/hisite-template]: https://github.com/hiqdev/hisite-template 50 | 51 | ## Idea 52 | 53 | The main goal of this theming library is to allow creation and use of easy 54 | pluggable themes: to change a theme on a site it is enough just to require 55 | other theme package in project's `composer.json`. 56 | 57 | To achieve this goal several technologies were used: 58 | 59 | - [Yii2 theming] with `pathMap` auto assembling; 60 | - [Yii2 dependency injection] for widgets and menus; 61 | - [composer-config-plugin] to create themes as plugins i.e. code combined and distributed 62 | together with configuration. 63 | 64 | This package provides: 65 | 66 | - bootrstrappable `ThemeManager` component that collects and setups in application view 67 | proper `Theme` object with proper `pathMap`; 68 | - widgets and menus that can be configured through params and substituted with DI; 69 | - theme `DebugPanel` showing actual `pathMap`. 70 | 71 | [composer-config-plugin]: https://github.com/hiqdev/composer-config-plugin 72 | [yii2 dependency injection]: http://www.yiiframework.com/doc-2.0/guide-concept-di-container.html 73 | [yii2 theming]: http://www.yiiframework.com/doc-2.0/guide-output-theming.html 74 | 75 | ## Configuration 76 | 77 | This extension is supposed to be used with [composer-config-plugin]. 78 | 79 | Also you can use it usual way by copy-pasting config. 80 | See [src/config/web.php] for configuration example. 81 | 82 | Available configuration parameters: 83 | 84 | - `themeManager.defaultTheme` - default theme 85 | - `copyright.year` - **CopyrightYears** widget 86 | - `copyright.years` 87 | - `logo.url` - **LogoLink** widget 88 | - `logo.name` 89 | - `logo.options` 90 | - `logo.image` 91 | - `logo.imageOptions` 92 | - `logo.smallImage` 93 | - `logo.smallImageOptions` 94 | - `organization.url` - **OrganizationLink** widget 95 | - `organization.name` 96 | - `organization.options` 97 | - `poweredBy.url` - **PoweredBy** widget 98 | - `poweredBy.name` 99 | - `poweredBy.version` 100 | - `poweredBy.options` 101 | - `socialLinks.links` - **SocialLinks** widget 102 | 103 | For more details please see [src/config/params.php]. 104 | 105 | [composer-config-plugin]: https://github.com/hiqdev/composer-config-plugin 106 | [src/config/params.php]: src/config/params.php 107 | [src/config/web.php]: src/config/web.php 108 | 109 | ## License 110 | 111 | This project is released under the terms of the BSD-3-Clause [license](LICENSE). 112 | Read more [here](http://choosealicense.com/licenses/bsd-3-clause). 113 | 114 | Copyright © 2015-2017, HiQDev (http://hiqdev.com/) 115 | -------------------------------------------------------------------------------- /src/widgets/LoginForm.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class LoginForm extends \yii\base\Widget 20 | { 21 | public $model; 22 | public $isCaptchaRequired = false; 23 | public $options = []; 24 | 25 | public $shows = []; 26 | public $pages = []; 27 | public $texts = []; 28 | public $disables = []; 29 | 30 | protected $_textAttributes; 31 | protected $_boolAttributes; 32 | protected $_defaultTexts; 33 | 34 | public function init() 35 | { 36 | parent::init(); 37 | $defaults = ['id' => 'login-form']; 38 | if (!empty($this->options['validationUrl'])) { 39 | $defaults['enableAjaxValidation'] = true; 40 | } 41 | $this->options = array_merge($defaults, $this->options); 42 | } 43 | 44 | public function run() 45 | { 46 | return $this->render('LoginForm', [ 47 | 'model' => $this->model, 48 | 'widget' => $this, 49 | ]); 50 | } 51 | 52 | public function isShown($action) 53 | { 54 | return empty($this->disables[$action]) && !empty($this->shows[$action]); 55 | } 56 | 57 | public function getPage($action) 58 | { 59 | return $this->isShown($action) ? $this->buildPage($this->getPageBase($action)) : null; 60 | } 61 | 62 | public function getPageBase($action) 63 | { 64 | return isset($this->pages[$action]) ? $this->pages[$action] : $action; 65 | } 66 | 67 | protected function buildPage($page) 68 | { 69 | if (!$page) { 70 | return null; 71 | } 72 | if (!is_array($page)) { 73 | $page = [$page]; 74 | } 75 | if (!isset($page['username']) && isset($this->model->username)) { 76 | $page['username'] = $this->model->username; 77 | } 78 | 79 | return $page; 80 | } 81 | 82 | public function getText($action) 83 | { 84 | return isset($this->texts[$action]) ? $this->texts[$action] : $this->getDefaultText($action); 85 | } 86 | 87 | public function getDefaultText($action) 88 | { 89 | if ($action === 'header' || $action === 'button') { 90 | return Yii::$app->view->title; 91 | } 92 | if (empty($this->_defaultTexts)) { 93 | $this->_defaultTexts = $this->defaultTexts(); 94 | } 95 | 96 | return isset($this->_defaultTexts[$action]) ? $this->_defaultTexts[$action] : null; 97 | } 98 | 99 | public function defaultTexts() 100 | { 101 | return [ 102 | 'restore-password' => Yii::t('hiqdev.thememanager', 'I forgot my password'), 103 | 'signup' => Yii::t('hiqdev.thememanager', 'Register a new membership'), 104 | 'login' => Yii::t('hiqdev.thememanager', 'I already have a membership'), 105 | ]; 106 | } 107 | 108 | public function detectInputIcon($name) 109 | { 110 | static $marks = [ 111 | 'old_password' => 'lock', 112 | 'password' => 'lock', 113 | 'password_retype' => 'sign-in', 114 | 'username' => 'envelope', 115 | 'email' => 'envelope', 116 | 'first_name' => 'user', 117 | 'last_name' => 'user', 118 | ]; 119 | 120 | return isset($marks[$name]) ? $marks[$name] : ''; 121 | } 122 | 123 | public function detectInputType($name) 124 | { 125 | return strpos($name, 'password') === false ? 'text' : 'password'; 126 | } 127 | 128 | public function getTextAttributes() 129 | { 130 | if ($this->_textAttributes === null) { 131 | $this->_textAttributes = []; 132 | $bools = $this->getBoolAttributes(); 133 | foreach ($this->model->activeAttributes() as $attribute) { 134 | if (empty($bools[$attribute])) { 135 | $this->_textAttributes[$attribute] = $attribute; 136 | } 137 | } 138 | } 139 | 140 | return $this->_textAttributes; 141 | } 142 | 143 | public function getBoolAttributes() 144 | { 145 | if ($this->_boolAttributes === null) { 146 | $this->_boolAttributes = []; 147 | foreach ($this->model->rules() as $rule) { 148 | if ($rule[1] === 'boolean') { 149 | $attributes = (array) $rule[0]; 150 | foreach ($attributes as $attribute) { 151 | if ($this->model->isAttributeActive($attribute)) { 152 | $this->_boolAttributes[$attribute] = $attribute; 153 | } 154 | } 155 | } 156 | } 157 | } 158 | 159 | return $this->_boolAttributes; 160 | } 161 | 162 | public function getBoolAttribute() 163 | { 164 | return reset($this->getBoolAttributes()); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/ThemeManager.php: -------------------------------------------------------------------------------- 1 | [ 31 | * 'themeManager' => [ 32 | * 'class' => \hiqdev\thememanager\ThemeManager::class, 33 | * ], 34 | * ] 35 | * ``` 36 | * 37 | * @author Andrii Vasyliev 38 | */ 39 | class ThemeManager extends \hiqdev\yii2\collection\Manager implements \yii\base\BootstrapInterface 40 | { 41 | /** 42 | * @var array basic pathMap for all themes, will be merged with theme own pathMap 43 | */ 44 | public $pathMap = []; 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | protected $_itemClass = Theme::class; 50 | 51 | /** 52 | * @var string default theme name 53 | */ 54 | protected $_defaultTheme; 55 | 56 | /** 57 | * Sets the default theme name. 58 | * 59 | * @param string $theme default theme name 60 | */ 61 | public function setDefaultTheme($theme) 62 | { 63 | $this->_defaultTheme = $theme; 64 | } 65 | 66 | /** 67 | * Returns the default theme. Returns the first of available themes by default. 68 | * 69 | * @return string default theme name 70 | */ 71 | public function getDefaultTheme() 72 | { 73 | if (!$this->_defaultTheme) { 74 | $keys = $this->keys(); /// shame to PHP it can't be done in single line :( 75 | $this->_defaultTheme = reset($keys); 76 | } 77 | 78 | return $this->_defaultTheme; 79 | } 80 | 81 | protected $_view; 82 | 83 | /** 84 | * @return \yii\web\View 85 | * @see setView 86 | */ 87 | public function getView() 88 | { 89 | if ($this->_view === null) { 90 | $this->_view = Yii::$app->getView(); 91 | } 92 | 93 | return $this->_view; 94 | } 95 | 96 | /** 97 | * You can change the View for theme manager. 98 | * @param \yii\web\View $view the view object that will be used to render views or view files 99 | */ 100 | public function setView($view) 101 | { 102 | $this->_view = $view; 103 | } 104 | 105 | /** 106 | * @var Theme current theme object 107 | */ 108 | protected $_theme; 109 | 110 | /** 111 | * Changes theme. 112 | * @param string theme name 113 | * @throws InvalidConfigException 114 | */ 115 | public function setTheme($name) 116 | { 117 | if (!$name) { 118 | throw new InvalidConfigException('no theme to set'); 119 | } 120 | $this->_theme = $name; 121 | } 122 | 123 | public function getTheme() 124 | { 125 | $this->ensureBootstrapped(); 126 | 127 | if (is_string($this->_theme)) { 128 | if (!$this->has($this->_theme)) { 129 | throw new InvalidConfigException('unknown theme: ' . $this->_theme); 130 | } 131 | $this->_theme = $this->getItem($this->_theme); 132 | $this->getView()->theme = $this->_theme; 133 | } 134 | 135 | return $this->_theme; 136 | } 137 | 138 | public function getSettings() 139 | { 140 | return $this->getTheme()->getSettings(); 141 | } 142 | 143 | /** 144 | * @return bool 145 | */ 146 | public static function isHomePage() 147 | { 148 | // todo: if route is change during the request processing the result will be outdated 149 | static $result = null; 150 | 151 | if ($result === null) { 152 | /** @var Controller $controller */ 153 | $actualRoute = Yii::$app->controller->getRoute(); 154 | 155 | [$controller, $actionId] = Yii::$app->createController(''); 156 | $actionId = !empty($actionId) ? $actionId : $controller->defaultAction; 157 | $defaultRoute = $controller->getUniqueId() . '/' . $actionId; 158 | 159 | $result = $actualRoute === $defaultRoute; 160 | } 161 | 162 | return $result; 163 | } 164 | 165 | /** 166 | * @var AssetBundle[] assets to be registered at bootstrap 167 | */ 168 | public $assets = []; 169 | 170 | /** 171 | * Register all the assets. 172 | */ 173 | public function registerAssets() 174 | { 175 | foreach (array_merge($this->assets, $this->getTheme()->assets) as $asset) { 176 | /** @var AssetBundle $asset */ 177 | $asset::register($this->getView()); 178 | } 179 | } 180 | 181 | /** 182 | * @var bool is already bootstrapped 183 | */ 184 | protected $_isBootstrapped = false; 185 | 186 | public function ensureBootstrapped() 187 | { 188 | if ($this->_isBootstrapped) { 189 | return; 190 | } 191 | $this->_isBootstrapped = true; 192 | 193 | Yii::debug('Bootstrap themes', get_called_class() . '::bootstrap'); 194 | 195 | $data = $this->getThemeSettings(); 196 | $model = new Settings(); 197 | $model->load($data); 198 | $theme = $this->hasItem($model->theme) ? $model->theme : null; 199 | $theme = $theme ?: $this->getDefaultTheme(); 200 | $this->setTheme($theme); 201 | $this->getTheme(); 202 | } 203 | 204 | /** 205 | * @return SettingsStorageInterface 206 | */ 207 | public function getSettingsStorage() 208 | { 209 | return Yii::$app->get('themeSettingsStorage'); 210 | } 211 | 212 | /** 213 | * @return array 214 | */ 215 | public function getThemeSettings() 216 | { 217 | return $this->getSettingsStorage()->get(); 218 | } 219 | 220 | public function bootstrap($app): void 221 | { 222 | if (!$app->has('view')) { 223 | return; 224 | } 225 | $app->on($app::EVENT_BEFORE_ACTION, [$this, 'ensureBootstrapped']); 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /src/Theme.php: -------------------------------------------------------------------------------- 1 | _view === null) { 52 | $this->_view = $this->getManager()->getView(); 53 | } 54 | 55 | return $this->_view; 56 | } 57 | 58 | /** 59 | * Sets the view object to be used. 60 | * 61 | * @param View $view the view object that can be used to render views or view files 62 | */ 63 | public function setView($view) 64 | { 65 | $this->_view = $view; 66 | } 67 | 68 | public $pathMap = []; 69 | 70 | /** 71 | * Getter for pathMap. 72 | */ 73 | public function init() 74 | { 75 | parent::init(); 76 | if (!is_array($this->pathMap)) { 77 | $this->pathMap = []; 78 | } 79 | 80 | $this->pathMap = $this->compilePathMap(ArrayHelper::merge([ 81 | '$themedViewPaths' => $this->buildThemedViewPaths(), 82 | '$themedWidgetPaths' => '$themedViewPaths/widgets', 83 | Yii::$app->viewPath => '$themedViewPaths', 84 | __DIR__ . '/widgets/views' => '$themedWidgetPaths', 85 | ], $this->getManager()->pathMap, $this->pathMap)); 86 | } 87 | 88 | public function compilePathMap($map) 89 | { 90 | $map = $this->substituteVars($map); 91 | 92 | $themeSubpath = '/src/views/themes/' . $this->name; 93 | 94 | $res = []; 95 | foreach ($map as $from => &$tos) { 96 | $tos = array_unique(array_reverse(array_values($tos))); 97 | $new = []; 98 | foreach ($tos as $to) { 99 | $to = Yii::getAlias($to); 100 | $alt = preg_replace('#(.*)/src/views(.*)$#', '${1}' . $themeSubpath . '${2}', $to); 101 | if ($alt) { 102 | $new[] = $alt; 103 | } 104 | $new[] = $to; 105 | } 106 | //$res[Yii::getAlias($from)] = $new; 107 | $res[Yii::getAlias($from)] = array_values(array_filter($new, 'file_exists')); 108 | } 109 | 110 | return array_filter($res); 111 | } 112 | 113 | public function substituteVars($vars) 114 | { 115 | $proceed = true; 116 | while ($proceed) { 117 | $proceed = false; 118 | foreach ($vars as $key => $exp) { 119 | if ($this->isVar($exp)) { 120 | $value = $this->calcExp($exp, $vars); 121 | if (isset($value)) { 122 | $vars[$key] = $value; 123 | $proceed = true; 124 | } 125 | } 126 | } 127 | } 128 | 129 | foreach (array_keys($vars) as $key) { 130 | if ($this->isVar($key)) { 131 | unset($vars[$key]); 132 | } 133 | } 134 | 135 | return $vars; 136 | } 137 | 138 | public function isVar($name) 139 | { 140 | return is_string($name) && (strncmp($name, '$', 1) === 0); 141 | } 142 | 143 | public function calcExp($exp, $vars) 144 | { 145 | $pos = strpos($exp, '/'); 146 | if ($pos === false) { 147 | return $vars[$exp]; 148 | } 149 | list($name, $suffix) = explode('/', $exp, 2); 150 | 151 | return array_map(function ($a) use ($suffix) { 152 | return "$a/$suffix"; 153 | }, $vars[$name]); 154 | } 155 | 156 | public function buildThemedViewPaths() 157 | { 158 | return array_map(function ($a) { 159 | return "$a/views"; 160 | }, $this->findParentPaths()); 161 | } 162 | 163 | public function findParentPaths() 164 | { 165 | $dirs = []; 166 | $ref = $this->getReflection(); 167 | for ($depth = 0; $depth < 10; ++$depth) { 168 | $dirs[] = dirname($ref->getFileName()); 169 | $ref = $ref->getParentClass(); 170 | if (__CLASS__ === $ref->name) { 171 | break; 172 | } 173 | } 174 | 175 | return $dirs; 176 | } 177 | 178 | protected $_reflection; 179 | 180 | public function getReflection() 181 | { 182 | if (!$this->_reflection) { 183 | $this->_reflection = new ReflectionClass($this); 184 | } 185 | 186 | return $this->_reflection; 187 | } 188 | 189 | private $_settings; 190 | 191 | /** 192 | * @param string $settings theme settings model class name or config 193 | */ 194 | public function setSettings($settings) 195 | { 196 | $this->_settings = $settings; 197 | } 198 | 199 | public function getSettings() 200 | { 201 | if (!is_object($this->_settings)) { 202 | if (!$this->_settings) { 203 | $this->_settings = static::findSettingsClass(get_called_class()); 204 | } 205 | $data = $this->getManager()->getThemeSettings(); 206 | $this->_settings = Yii::createObject($this->_settings); 207 | $this->_settings->load($data); 208 | } 209 | 210 | return $this->_settings; 211 | } 212 | 213 | public static function calcSettingsClass($class) 214 | { 215 | return substr($class, 0, strrpos($class, '\\')) . '\\models\\Settings'; 216 | } 217 | 218 | public static function findSettingsClass($class) 219 | { 220 | $res = static::calcSettingsClass($class); 221 | 222 | return class_exists($res) ? $res : static::findSettingsClass(get_parent_class($class)); 223 | } 224 | 225 | public function getDetailedTheme() 226 | { 227 | $localDetailedTheme = str_replace('\Theme', '\DetailedTheme', get_called_class()); 228 | $class = class_exists($localDetailedTheme) ? $localDetailedTheme : DetailedTheme::class; 229 | 230 | return new $class($this); 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /history.md: -------------------------------------------------------------------------------- 1 | # hiqdev/yii2-thememanager 2 | 3 | ## [0.4.1] - 2022-06-29 4 | 5 | - ThemeManager have to set View::theme before render 6 | - [1b52083] 2022-06-29 ThemeManager have to set View::theme before render [@SilverFire] 7 | 8 | ## [0.4.0] - 2022-06-29 9 | 10 | - [8cf602a] 2022-06-28 Released 0.4.0 [@SilverFire] 11 | - Do not initialize a session connect unless required 12 | - [a01e793] 2022-06-28 Do not initialize a session connect unless required [@SilverFire] 13 | - Added `AlertWidget` 14 | - [2ba8f11] 2020-03-26 Added `AlertWidget` [@tafid] 15 | - [4676742] 2019-10-30 Merge pull request #5 from strorch/feature/captcha [@SilverFire] 16 | - LoginForm::getBoolAttributes() will be retrun scenario active only 17 | - [424d425] 2019-07-19 LoginForm::getBoolAttributes() will be retrun scenario active only [@tafid] 18 | - Other minor changes 19 | - [7822e7e] 2021-02-18 typo [smy980807@ukr.net] 20 | - [91d3d3f] 2020-10-02 removed small image from LogoLink view [smy980807@ukr.net] 21 | - [c8603a0] 2020-07-15 DANGEROUS: Fix (hopefully) theme compile path map [@hiqsol] 22 | - [b3ad004] 2020-07-07 fixed aliased paths to real [smy980807@ukr.net] 23 | - [3ccd8e5] 2020-03-26 Merge pull request #7 from tafid/alert_widget [@SilverFire] 24 | - [f557e68] 2019-10-25 created captcha field in LoginForm [smy980807@ukr.net] 25 | - [63ce3b1] 2019-08-29 Fixed for Yii 2 [@hiqsol] 26 | - [0817fdd] 2019-03-08 Moved config to root dir [@hiqsol] 27 | - [6137867] 2018-07-11 removed use of `Yii::getAlias` [@hiqsol] 28 | 29 | ## [0.3.2] - 2022-06-29 30 | 31 | - Fixed minor issues 32 | - [9b75f27] 2017-10-03 csfixed [@hiqsol] 33 | - [364fdff] 2017-08-18 Deleted FAQ js from root [@tafid] 34 | - [422a47b] 2017-06-19 redone translation category to `hiqdev.thememanager` [@hiqsol] 35 | - [7fcb548] 2017-06-13 fixed typo [@hiqsol] 36 | - Added `NavbarMenu` 37 | - [033c02d] 2017-05-10 added `NavbarMenu` [@hiqsol] 38 | - Moved theme tuning views to `src/views/themes` <- src/themes 39 | - [f279ab0] 2017-05-10 moved theme tuning views to `src/views/themes` <- `src/themes` [@hiqsol] 40 | - [bdc23c2] 2017-05-08 csfixed [@hiqsol] 41 | - Improved docs 42 | - [f2b73ec] 2017-05-08 docs [@hiqsol] 43 | - [968be6d] 2017-05-08 docs [@hiqsol] 44 | - [cd4f3cb] 2017-05-07 docs [@hiqsol] 45 | - Added `Markdown` widget 46 | - [9a14757] 2017-05-07 added Markdown widget [@hiqsol] 47 | - [76c23de] 2017-05-06 csfixed [@hiqsol] 48 | - Fixed configs 49 | - [4cddce8] 2017-05-06 renamed `hidev.yml` [@hiqsol] 50 | - [85de120] 2017-05-06 renamed config `web` <- hisite [@hiqsol] 51 | - [523ac50] 2017-04-23 docs [@hiqsol] 52 | - [f1ac15b] 2017-04-19 renamed all parameters to dot.style with defaults in params.php [@hiqsol] 53 | - [f994a12] 2017-04-19 renamed param `socialLinks.links` <- socialLinks [@hiqsol] 54 | 55 | ## [0.3.1] - 2022-06-29 56 | 57 | - Renamed poweredBy params to dot style 58 | - [3680fe3] 2017-04-19 csfixed [@hiqsol] 59 | - [833abe5] 2017-04-16 renamed poweredBy params to dot style [@hiqsol] 60 | - Added `OrientationInterface` 61 | - [f8a2287] 2017-04-12 Added setGlobalOrientation() method, rename getSettingsStorage method to getThemeSettingsStorage [@tafid] 62 | - [76f5f2c] 2017-03-23 Added OrientationInterface [@tafid] 63 | - [ae0e0b2] 2017-03-23 Added implements to OrientationInterface [@tafid] 64 | - Added `themeManager.defaultTheme` parameter 65 | - [31d2dae] 2017-04-16 added themeManager.defaultTheme parameter [@hiqsol] 66 | - Added Faq, FancyPanel widgets 67 | - [1d55f1f] 2017-02-10 Deleted faq.css, remove it from FaqAsset [@tafid] 68 | - [ee3630e] 2017-02-07 Added Faq assets [@tafid] 69 | - [f5472ea] 2017-02-07 Added Faq widget [@tafid] 70 | - [b4d7c94] 2017-02-07 Added view file for FancyPanel widget [@tafid] 71 | - Added in-site theming 72 | - [19cc7fa] 2017-02-06 improved building pathMap: added in-site theming [@hiqsol] 73 | - Added LogoLink widget 74 | - [2c072a4] 2017-03-29 Changed logo param names [@tafid] 75 | - [34a0321] 2017-03-29 Improved LogoLink::getImage() method, now it can works with urls [@tafid] 76 | - [12fb0c3] 2017-03-29 Changed marckup in LogoLink widget view file [@tafid] 77 | - [d7f1dd5] 2017-03-11 added imageOptions param [@hiqsol] 78 | - [a591721] 2017-02-02 Moved obaju LogoLink to thememanager LogoLink [@tafid] 79 | - [a812c8a] 2017-02-02 fixed enabling debug with `debug.enabled` param <- `YII_DEBUG_MODULE` constant [@hiqsol] 80 | - Added `DetailedTheme` class 81 | - [051f14d] 2017-01-30 Added new attribute DetailedTheme::licenseText [@tafid] 82 | - [660e3eb] 2017-01-30 Specified the path to the DetailedTheme files [@tafid] 83 | - [dc48a87] 2017-01-26 Shortened getDetailedTheme method [@tafid] 84 | - [ae44253] 2017-01-25 Added base DetailedTheme class [@tafid] 85 | - [4dc0217] 2017-01-25 Added getDetailedTheme method [@tafid] 86 | - [47b0aba] 2017-01-24 Added linkOptions attribute [@tafid] 87 | - [489beb1] 2017-01-19 Improved isHomePage, used getRoute() [@tafid] 88 | - [8040d38] 2017-01-19 Fixed isHomePage method [@tafid] 89 | 90 | ## [0.3.0] - 2022-06-29 91 | 92 | - Fixed minor issues 93 | - [645bac7] 2017-01-12 csfixed [@hiqsol] 94 | - [ea1c1cd] 2016-12-30 Translations updated [@SilverFire] 95 | - [f300ba3] 2016-12-30 Added a unified method for producing an image from a theme asset [@tafid] 96 | - [43a4ccb] 2016-12-30 Improved collect data [@tafid] 97 | - [77dac5b] 2016-12-29 Use `YII_DEBUG_MODULE` constant instead of `YII_DEBUG` to add thememanager panel [@SilverFire] 98 | - [37941a7] 2016-12-23 doc [@hiqsol] 99 | - [5b2a1a3] 2016-12-19 redone translation category to `hiqdev:thememanager` [@hiqsol] 100 | - [466ba7d] 2016-12-19 redone translation category to `hiqdev:thememanager` [@hiqsol] 101 | - Added Faq and TextPage widgets 102 | - [54a2c07] 2016-12-23 Added Faq widget [@tafid] 103 | - [9c38c60] 2016-12-21 Added TextPage widget [@tafid] 104 | - Added abstract menus 105 | - [c829c74] 2016-12-22 + AbstractFooterMenu [@hiqsol] 106 | - [6425fcb] 2016-12-22 + SidebarMenu widget [@hiqsol] 107 | - [c64be6c] 2016-12-21 fixed menu interface: widget -> run, render -> widget [@hiqsol] 108 | - [865f3a1] 2016-12-20 + abstract menus [@hiqsol] 109 | - Removed widget, hasWidget and callStatic from ThemeManager, redone creating widgets to straight yii DI 110 | - [b59dfe6] 2016-12-21 redone Menu::render -> widget [@hiqsol] 111 | - [7356b05] 2016-12-21 removed widget, hasWidget and callStatic from ThemeManager [@hiqsol] 112 | - [407d4b8] 2016-12-21 + abstract menus [@hiqsol] 113 | - [f92ab1d] 2016-12-21 + Flashes widget (empty) [@hiqsol] 114 | - [65ed824] 2016-12-21 improved UserMenu widget [@hiqsol] 115 | - [c2fb625] 2016-12-20 redone config for straight DI [@hiqsol] 116 | 117 | ## [0.2.0] - 2022-06-29 118 | 119 | - Added UserMenu, FancyPanel 120 | - [f7761a3] 2016-12-03 csfixed: changed header comment to phpdoc [@hiqsol] 121 | - [86eeff5] 2016-12-03 csfixed [@hiqsol] 122 | - [6a56a9e] 2016-12-03 used hidev-hiqdev instead of hidev-vendor [@hiqsol] 123 | - [143104e] 2016-12-02 used proper container definitions setting [@hiqsol] 124 | - [28c0c5e] 2016-11-29 translation [@tafid] 125 | - [ac24ec6] 2016-11-16 redone dependencies to definitions [@hiqsol] 126 | - [db5f0d8] 2016-11-16 added UserMenu widget [@hiqsol] 127 | - [c793f5f] 2016-11-16 redone widgets to yii dependency injection [@hiqsol] 128 | - [add8772] 2016-11-03 improved debug config [@hiqsol] 129 | - [6e0afba] 2016-10-25 csfixed [@hiqsol] 130 | - [f8c6d00] 2016-10-25 translations [@hiqsol] 131 | - [1f54379] 2016-10-20 Added php doc, added options to Html::img [@tafid] 132 | - [fdf724a] 2016-10-20 Removed NotSupported exception, publish logo [@tafid] 133 | - [34f2fe3] 2016-10-20 Fixed wrong message source [@SilverFire] 134 | - [46259ef] 2016-10-19 Fixed Settings::load() to work with defaults [@SilverFire] 135 | - [d09a08b] 2016-10-19 fixed for PHP 7.0 compatibility [@hiqsol] 136 | - [8dfae0a] 2016-10-06 Added FancyPanel widget [@tafid] 137 | - Fixed many widgets 138 | - [8c23df8] 2016-10-23 redone SocialLinks widget [@hiqsol] 139 | - [65d6081] 2016-10-21 fixed LogoLink widget when no image given [@hiqsol] 140 | - [5d526c9] 2016-10-14 simplified LoginForm pages, shows, texts, disables [@hiqsol] 141 | - [f489bcd] 2016-10-14 + get text/bool attributes, init options and detectIcons [@hiqsol] 142 | - [6b68562] 2016-10-13 greatly improved LoginForm to be suitable for any login-like pages: signup, restore-password, reset-password [@hiqsol] 143 | - [f5b4445] 2016-10-12 * LoginForm: + signup & restore password page options [@hiqsol] 144 | - [9d8d39c] 2016-10-11 fixed CopyrightYears widget [@hiqsol] 145 | - Added SessionSettingsStorage 146 | - [5b1b174] 2016-10-19 Implemented SettingsStorage usage [@SilverFire] 147 | - [1e32601] 2016-10-19 Added SessionSettingsStorage [@SilverFire] 148 | - [bed82dc] 2016-10-17 added detectInputType in LoginForm widget [@hiqsol] 149 | - Added Themes debug panel 150 | - [0ebb43c] 2016-10-02 added themes debug panel [@hiqsol] 151 | - Changed building pathMap 152 | - [b99abb3] 2016-10-01 improved building pathMap again with themes own pathMap [@hiqsol] 153 | - [022202a] 2016-09-29 improved building pathMap: adding app viewPath mapping by default and resolving aliases in pathMap [@hiqsol] 154 | 155 | ## [0.1.0] - 2022-06-29 156 | 157 | - Changed: redone building theme pathMap with vars substituting 158 | - [cc5e84c] 2016-09-28 redone building theme pathMap with compilePathMap and substituteVars [@hiqsol] 159 | - [429f3ec] 2016-09-28 redone building pathMap with viewPath, widgetPaths and themedPaths [@hiqsol] 160 | - Changed: redone widgets to pass params through config 161 | - [ef55143] 2016-09-21 redone widgets to pass params through config not code [@hiqsol] 162 | - [adb42d2] 2016-09-21 used original `widget()` function [@hiqsol] 163 | - [4fbc1bc] 2016-09-19 Change poweredBy view, add thememanager translate messages [@tafid] 164 | 165 | ## [0.0.2] - 2022-06-29 166 | 167 | - Added widgets: OrganizationLink, SocialLinks, PoweredBy, LoginForm, Breadcrumbs 168 | - [d675571] 2016-09-02 added LoginForm widget [@hiqsol] 169 | - [40907ee] 2016-09-01 + PoweredBy widget [@hiqsol] 170 | - [a3dbaec] 2016-09-01 + widget path to pathMap [@hiqsol] 171 | - [f497ed7] 2016-08-26 added Breadcrumbs widget [@hiqsol] 172 | - [4ca3a60] 2016-08-26 + hasWidget() [@hiqsol] 173 | - [e2a5674] 2016-08-26 added Flash for Theme changed [@hiqsol] 174 | - [4eeb955] 2016-08-25 Fixed OrganizationLink from trim(variable) to trim(variable) !== "" [@tafid] 175 | - [ce60121] 2016-08-25 fixed OrganizationLink widget to use organizationName/Url [@hiqsol] 176 | - [97b9234] 2016-08-25 fixed typo [@hiqsol] 177 | - [f834412] 2016-08-25 Added SocialLinks widget, complemented OrganizationLink widget [@tafid] 178 | - [7d19283] 2016-08-25 added widgets [@hiqsol] 179 | - [a26edd8] 2016-08-25 + ThemeManager::widget() [@hiqsol] 180 | - [4730098] 2016-08-23 Grammar fix [@tafid] 181 | - Added viewPaths parameter 182 | - [e8a26cf] 2016-09-02 csfixed [@hiqsol] 183 | - [6190dc6] 2016-08-31 redone pathDirs -> viewPaths [@hiqsol] 184 | - [f2713bf] 2016-08-28 forced adding pathDirs in Theme [@hiqsol] 185 | - [10092cc] 2016-08-22 + pathDirs parameter [@hiqsol] 186 | - Removed View, AssetConverter and AssetManager 187 | - [1f9a236] 2016-08-23 removed View, AssetConverter and AssetManager [@hiqsol] 188 | - [87125e7] 2016-08-23 removed AssetManager from bootstrap [@hiqsol] 189 | - [ea0c7a7] 2016-08-23 removed AssetManager from config [@hiqsol] 190 | 191 | ## [0.0.1] - 2022-06-29 192 | 193 | - Changed bootstrapping 194 | - [ef164cf] 2016-08-19 + isHomePage to ThemeManager component [@hiqsol] 195 | - [d90ee48] 2016-08-19 csfixed [@hiqsol] 196 | - [0d9f909] 2016-08-18 + isHomePage() [@hiqsol] 197 | - [0393701] 2016-08-13 changed bootstrapping not finished [@hiqsol] 198 | - [87a496c] 2016-08-13 + bootstrap themeManager [@hiqsol] 199 | - [b2dd956] 2016-07-16 csfixed [@hiqsol] 200 | - Changed: redone to `composer-config-plugin` 201 | - [46bc352] 2016-05-20 fixed module adding, removed Plugin.php [@hiqsol] 202 | - [14ed956] 2016-05-19 redone to composer-config-plugin [@hiqsol] 203 | - [0b8316a] 2016-05-04 inited tests [@hiqsol] 204 | - [95a5da1] 2016-05-04 changed ThemeManager to be more lazy in setting theme [@hiqsol] 205 | - [2b63cdc] 2016-05-04 added views and widgets path parametrizing [@hiqsol] 206 | - [5a428dc] 2016-04-29 csfixed [@hiqsol] 207 | - [c440e44] 2016-04-29 rehideved [@hiqsol] 208 | - [9c06c71] 2016-04-29 redone `yii2-extraconfig.php` to `hisite-config.php` [@hiqsol] 209 | - [91f43e8] 2016-02-29 + require yii2-collection [@hiqsol] 210 | - [94faceb] 2016-02-29 removing bootstrapping [@hiqsol] 211 | - [a0e282c] 2016-02-29 + yii-extraconfig [@hiqsol] 212 | - [cbb82cb] 2016-02-24 - require plugin manager [@hiqsol] 213 | - Fixed minor issues 214 | - [7f5d47f] 2016-02-24 phpcsfixed [@hiqsol] 215 | - [650863d] 2016-02-24 rehideved [@hiqsol] 216 | - [c85f4dd] 2016-02-17 fixed PHP notice [@hiqsol] 217 | - [3898f12] 2016-01-27 Add renderAjax if request isAjax [@tafid] 218 | - [219c4e1] 2015-12-09 Fixed Settings::load() signature [@SilverFire] 219 | - [108f84d] 2015-11-23 Changed namespace to yii2-collection [@SilverFire] 220 | - [479f995] 2015-11-05 Chaching placeholders removed [@SilverFire] 221 | - Fixed getting current theme 222 | - [c5ad453] 2016-02-24 added parameters checks [@hiqsol] 223 | - [3b8e173] 2015-08-25 fixed getting current theme [@hiqsol] 224 | - [d3afbe9] 2015-08-18 + better getting default theme [@hiqsol] 225 | - Changed: moved to src 226 | - [18e4255] 2015-08-18 php-cs-fixed [@hiqsol] 227 | - [9fc695f] 2015-08-18 + `.php_cs` [@hiqsol] 228 | - [f46612a] 2015-08-18 moved to src [@hiqsol] 229 | - [10f3fa6] 2015-08-18 moved to src [@hiqsol] 230 | - [b0aa3f5] 2015-08-18 moved to src [@hiqsol] 231 | - [68e389d] 2015-08-18 rehideved with new features: better README and .gitignore [@hiqsol] 232 | - Added AssetManager and AssetConverter 233 | - [87ca207] 2015-06-12 improved RegisterAssets - moved to ThemeManager [@hiqsol] 234 | - [28c4cd5] 2015-06-11 + AssetConverter [@hiqsol] 235 | - [a64ccb3] 2015-06-11 + AssetManager, renamed to ThemeManager [@hiqsol] 236 | - [a703a1b] 2015-06-10 * Theme: + assets and get/registerAssets [@hiqsol] 237 | - Added basics 238 | - [765ff2a] 2015-06-10 hideved [@hiqsol] 239 | - [7c492ea] 2015-06-10 + proper finding settings class at Theme [@hiqsol] 240 | - [a95617b] 2015-06-02 fixed theme saving [@hiqsol] 241 | - [b0d0772] 2015-05-29 simplified access to current theme settings [@hiqsol] 242 | - [874899d] 2015-05-28 Added missing use for InvalidConfigException [@SilverFire] 243 | - [0ee7e85] 2015-05-27 + Settings [@hiqsol] 244 | - [42d384c] 2015-05-26 hideved [@hiqsol] 245 | - [73b4ea1] 2015-05-20 + real Manager and Theme [@hiqsol] 246 | - [3d9e1b3] 2015-04-18 doc [@hiqsol] 247 | - [40e739b] 2015-04-18 doc [@hiqsol] 248 | - [67527f2] 2015-04-18 inited [@hiqsol] 249 | 250 | ## [Development started] - 2022-06-29 251 | 252 | ## [dev] - 2022-06-29 253 | 254 | [@hiqsol]: https://github.com/hiqsol 255 | [sol@hiqdev.com]: https://github.com/hiqsol 256 | [@SilverFire]: https://github.com/SilverFire 257 | [d.naumenko.a@gmail.com]: https://github.com/SilverFire 258 | [@tafid]: https://github.com/tafid 259 | [andreyklochok@gmail.com]: https://github.com/tafid 260 | [@BladeRoot]: https://github.com/BladeRoot 261 | [bladeroot@gmail.com]: https://github.com/BladeRoot 262 | [46bc352]: https://github.com/hiqdev/yii2-thememanager/commit/46bc352 263 | [14ed956]: https://github.com/hiqdev/yii2-thememanager/commit/14ed956 264 | [0b8316a]: https://github.com/hiqdev/yii2-thememanager/commit/0b8316a 265 | [95a5da1]: https://github.com/hiqdev/yii2-thememanager/commit/95a5da1 266 | [2b63cdc]: https://github.com/hiqdev/yii2-thememanager/commit/2b63cdc 267 | [5a428dc]: https://github.com/hiqdev/yii2-thememanager/commit/5a428dc 268 | [c440e44]: https://github.com/hiqdev/yii2-thememanager/commit/c440e44 269 | [9c06c71]: https://github.com/hiqdev/yii2-thememanager/commit/9c06c71 270 | [91f43e8]: https://github.com/hiqdev/yii2-thememanager/commit/91f43e8 271 | [94faceb]: https://github.com/hiqdev/yii2-thememanager/commit/94faceb 272 | [a0e282c]: https://github.com/hiqdev/yii2-thememanager/commit/a0e282c 273 | [cbb82cb]: https://github.com/hiqdev/yii2-thememanager/commit/cbb82cb 274 | [7f5d47f]: https://github.com/hiqdev/yii2-thememanager/commit/7f5d47f 275 | [650863d]: https://github.com/hiqdev/yii2-thememanager/commit/650863d 276 | [c85f4dd]: https://github.com/hiqdev/yii2-thememanager/commit/c85f4dd 277 | [3898f12]: https://github.com/hiqdev/yii2-thememanager/commit/3898f12 278 | [219c4e1]: https://github.com/hiqdev/yii2-thememanager/commit/219c4e1 279 | [108f84d]: https://github.com/hiqdev/yii2-thememanager/commit/108f84d 280 | [479f995]: https://github.com/hiqdev/yii2-thememanager/commit/479f995 281 | [c5ad453]: https://github.com/hiqdev/yii2-thememanager/commit/c5ad453 282 | [3b8e173]: https://github.com/hiqdev/yii2-thememanager/commit/3b8e173 283 | [d3afbe9]: https://github.com/hiqdev/yii2-thememanager/commit/d3afbe9 284 | [18e4255]: https://github.com/hiqdev/yii2-thememanager/commit/18e4255 285 | [9fc695f]: https://github.com/hiqdev/yii2-thememanager/commit/9fc695f 286 | [f46612a]: https://github.com/hiqdev/yii2-thememanager/commit/f46612a 287 | [10f3fa6]: https://github.com/hiqdev/yii2-thememanager/commit/10f3fa6 288 | [b0aa3f5]: https://github.com/hiqdev/yii2-thememanager/commit/b0aa3f5 289 | [68e389d]: https://github.com/hiqdev/yii2-thememanager/commit/68e389d 290 | [87ca207]: https://github.com/hiqdev/yii2-thememanager/commit/87ca207 291 | [28c4cd5]: https://github.com/hiqdev/yii2-thememanager/commit/28c4cd5 292 | [a64ccb3]: https://github.com/hiqdev/yii2-thememanager/commit/a64ccb3 293 | [a703a1b]: https://github.com/hiqdev/yii2-thememanager/commit/a703a1b 294 | [765ff2a]: https://github.com/hiqdev/yii2-thememanager/commit/765ff2a 295 | [7c492ea]: https://github.com/hiqdev/yii2-thememanager/commit/7c492ea 296 | [a95617b]: https://github.com/hiqdev/yii2-thememanager/commit/a95617b 297 | [b0d0772]: https://github.com/hiqdev/yii2-thememanager/commit/b0d0772 298 | [874899d]: https://github.com/hiqdev/yii2-thememanager/commit/874899d 299 | [0ee7e85]: https://github.com/hiqdev/yii2-thememanager/commit/0ee7e85 300 | [42d384c]: https://github.com/hiqdev/yii2-thememanager/commit/42d384c 301 | [73b4ea1]: https://github.com/hiqdev/yii2-thememanager/commit/73b4ea1 302 | [3d9e1b3]: https://github.com/hiqdev/yii2-thememanager/commit/3d9e1b3 303 | [40e739b]: https://github.com/hiqdev/yii2-thememanager/commit/40e739b 304 | [67527f2]: https://github.com/hiqdev/yii2-thememanager/commit/67527f2 305 | [ef164cf]: https://github.com/hiqdev/yii2-thememanager/commit/ef164cf 306 | [d90ee48]: https://github.com/hiqdev/yii2-thememanager/commit/d90ee48 307 | [0d9f909]: https://github.com/hiqdev/yii2-thememanager/commit/0d9f909 308 | [0393701]: https://github.com/hiqdev/yii2-thememanager/commit/0393701 309 | [87a496c]: https://github.com/hiqdev/yii2-thememanager/commit/87a496c 310 | [b2dd956]: https://github.com/hiqdev/yii2-thememanager/commit/b2dd956 311 | [4730098]: https://github.com/hiqdev/yii2-thememanager/commit/4730098 312 | [10092cc]: https://github.com/hiqdev/yii2-thememanager/commit/10092cc 313 | [e8a26cf]: https://github.com/hiqdev/yii2-thememanager/commit/e8a26cf 314 | [d675571]: https://github.com/hiqdev/yii2-thememanager/commit/d675571 315 | [40907ee]: https://github.com/hiqdev/yii2-thememanager/commit/40907ee 316 | [a3dbaec]: https://github.com/hiqdev/yii2-thememanager/commit/a3dbaec 317 | [6190dc6]: https://github.com/hiqdev/yii2-thememanager/commit/6190dc6 318 | [f2713bf]: https://github.com/hiqdev/yii2-thememanager/commit/f2713bf 319 | [f497ed7]: https://github.com/hiqdev/yii2-thememanager/commit/f497ed7 320 | [e2a5674]: https://github.com/hiqdev/yii2-thememanager/commit/e2a5674 321 | [4ca3a60]: https://github.com/hiqdev/yii2-thememanager/commit/4ca3a60 322 | [4eeb955]: https://github.com/hiqdev/yii2-thememanager/commit/4eeb955 323 | [ce60121]: https://github.com/hiqdev/yii2-thememanager/commit/ce60121 324 | [97b9234]: https://github.com/hiqdev/yii2-thememanager/commit/97b9234 325 | [f834412]: https://github.com/hiqdev/yii2-thememanager/commit/f834412 326 | [7d19283]: https://github.com/hiqdev/yii2-thememanager/commit/7d19283 327 | [a26edd8]: https://github.com/hiqdev/yii2-thememanager/commit/a26edd8 328 | [87125e7]: https://github.com/hiqdev/yii2-thememanager/commit/87125e7 329 | [ea0c7a7]: https://github.com/hiqdev/yii2-thememanager/commit/ea0c7a7 330 | [1f9a236]: https://github.com/hiqdev/yii2-thememanager/commit/1f9a236 331 | [cc5e84c]: https://github.com/hiqdev/yii2-thememanager/commit/cc5e84c 332 | [429f3ec]: https://github.com/hiqdev/yii2-thememanager/commit/429f3ec 333 | [ef55143]: https://github.com/hiqdev/yii2-thememanager/commit/ef55143 334 | [adb42d2]: https://github.com/hiqdev/yii2-thememanager/commit/adb42d2 335 | [4fbc1bc]: https://github.com/hiqdev/yii2-thememanager/commit/4fbc1bc 336 | [f7761a3]: https://github.com/hiqdev/yii2-thememanager/commit/f7761a3 337 | [86eeff5]: https://github.com/hiqdev/yii2-thememanager/commit/86eeff5 338 | [6a56a9e]: https://github.com/hiqdev/yii2-thememanager/commit/6a56a9e 339 | [143104e]: https://github.com/hiqdev/yii2-thememanager/commit/143104e 340 | [28c0c5e]: https://github.com/hiqdev/yii2-thememanager/commit/28c0c5e 341 | [ac24ec6]: https://github.com/hiqdev/yii2-thememanager/commit/ac24ec6 342 | [db5f0d8]: https://github.com/hiqdev/yii2-thememanager/commit/db5f0d8 343 | [c793f5f]: https://github.com/hiqdev/yii2-thememanager/commit/c793f5f 344 | [add8772]: https://github.com/hiqdev/yii2-thememanager/commit/add8772 345 | [6e0afba]: https://github.com/hiqdev/yii2-thememanager/commit/6e0afba 346 | [f8c6d00]: https://github.com/hiqdev/yii2-thememanager/commit/f8c6d00 347 | [8c23df8]: https://github.com/hiqdev/yii2-thememanager/commit/8c23df8 348 | [65d6081]: https://github.com/hiqdev/yii2-thememanager/commit/65d6081 349 | [1f54379]: https://github.com/hiqdev/yii2-thememanager/commit/1f54379 350 | [fdf724a]: https://github.com/hiqdev/yii2-thememanager/commit/fdf724a 351 | [34f2fe3]: https://github.com/hiqdev/yii2-thememanager/commit/34f2fe3 352 | [46259ef]: https://github.com/hiqdev/yii2-thememanager/commit/46259ef 353 | [d09a08b]: https://github.com/hiqdev/yii2-thememanager/commit/d09a08b 354 | [5b1b174]: https://github.com/hiqdev/yii2-thememanager/commit/5b1b174 355 | [1e32601]: https://github.com/hiqdev/yii2-thememanager/commit/1e32601 356 | [bed82dc]: https://github.com/hiqdev/yii2-thememanager/commit/bed82dc 357 | [5d526c9]: https://github.com/hiqdev/yii2-thememanager/commit/5d526c9 358 | [f489bcd]: https://github.com/hiqdev/yii2-thememanager/commit/f489bcd 359 | [6b68562]: https://github.com/hiqdev/yii2-thememanager/commit/6b68562 360 | [f5b4445]: https://github.com/hiqdev/yii2-thememanager/commit/f5b4445 361 | [9d8d39c]: https://github.com/hiqdev/yii2-thememanager/commit/9d8d39c 362 | [8dfae0a]: https://github.com/hiqdev/yii2-thememanager/commit/8dfae0a 363 | [0ebb43c]: https://github.com/hiqdev/yii2-thememanager/commit/0ebb43c 364 | [b99abb3]: https://github.com/hiqdev/yii2-thememanager/commit/b99abb3 365 | [022202a]: https://github.com/hiqdev/yii2-thememanager/commit/022202a 366 | [645bac7]: https://github.com/hiqdev/yii2-thememanager/commit/645bac7 367 | [ea1c1cd]: https://github.com/hiqdev/yii2-thememanager/commit/ea1c1cd 368 | [f300ba3]: https://github.com/hiqdev/yii2-thememanager/commit/f300ba3 369 | [43a4ccb]: https://github.com/hiqdev/yii2-thememanager/commit/43a4ccb 370 | [77dac5b]: https://github.com/hiqdev/yii2-thememanager/commit/77dac5b 371 | [37941a7]: https://github.com/hiqdev/yii2-thememanager/commit/37941a7 372 | [54a2c07]: https://github.com/hiqdev/yii2-thememanager/commit/54a2c07 373 | [c829c74]: https://github.com/hiqdev/yii2-thememanager/commit/c829c74 374 | [6425fcb]: https://github.com/hiqdev/yii2-thememanager/commit/6425fcb 375 | [c64be6c]: https://github.com/hiqdev/yii2-thememanager/commit/c64be6c 376 | [9c38c60]: https://github.com/hiqdev/yii2-thememanager/commit/9c38c60 377 | [b59dfe6]: https://github.com/hiqdev/yii2-thememanager/commit/b59dfe6 378 | [7356b05]: https://github.com/hiqdev/yii2-thememanager/commit/7356b05 379 | [407d4b8]: https://github.com/hiqdev/yii2-thememanager/commit/407d4b8 380 | [f92ab1d]: https://github.com/hiqdev/yii2-thememanager/commit/f92ab1d 381 | [65ed824]: https://github.com/hiqdev/yii2-thememanager/commit/65ed824 382 | [c2fb625]: https://github.com/hiqdev/yii2-thememanager/commit/c2fb625 383 | [865f3a1]: https://github.com/hiqdev/yii2-thememanager/commit/865f3a1 384 | [5b2a1a3]: https://github.com/hiqdev/yii2-thememanager/commit/5b2a1a3 385 | [466ba7d]: https://github.com/hiqdev/yii2-thememanager/commit/466ba7d 386 | [Under development]: https://github.com/hiqdev/yii2-thememanager/compare/0.3.2...HEAD 387 | [0.2.0]: https://github.com/hiqdev/yii2-thememanager/compare/0.1.0...0.2.0 388 | [0.1.0]: https://github.com/hiqdev/yii2-thememanager/compare/0.0.2...0.1.0 389 | [0.0.2]: https://github.com/hiqdev/yii2-thememanager/compare/0.0.1...0.0.2 390 | [0.0.1]: https://github.com/hiqdev/yii2-thememanager/releases/tag/0.0.1 391 | [0.3.0]: https://github.com/hiqdev/yii2-thememanager/compare/0.2.0...0.3.0 392 | [3680fe3]: https://github.com/hiqdev/yii2-thememanager/commit/3680fe3 393 | [833abe5]: https://github.com/hiqdev/yii2-thememanager/commit/833abe5 394 | [31d2dae]: https://github.com/hiqdev/yii2-thememanager/commit/31d2dae 395 | [f8a2287]: https://github.com/hiqdev/yii2-thememanager/commit/f8a2287 396 | [12fb0c3]: https://github.com/hiqdev/yii2-thememanager/commit/12fb0c3 397 | [2c072a4]: https://github.com/hiqdev/yii2-thememanager/commit/2c072a4 398 | [34a0321]: https://github.com/hiqdev/yii2-thememanager/commit/34a0321 399 | [76f5f2c]: https://github.com/hiqdev/yii2-thememanager/commit/76f5f2c 400 | [ae0e0b2]: https://github.com/hiqdev/yii2-thememanager/commit/ae0e0b2 401 | [d7f1dd5]: https://github.com/hiqdev/yii2-thememanager/commit/d7f1dd5 402 | [1d55f1f]: https://github.com/hiqdev/yii2-thememanager/commit/1d55f1f 403 | [ee3630e]: https://github.com/hiqdev/yii2-thememanager/commit/ee3630e 404 | [f5472ea]: https://github.com/hiqdev/yii2-thememanager/commit/f5472ea 405 | [b4d7c94]: https://github.com/hiqdev/yii2-thememanager/commit/b4d7c94 406 | [19cc7fa]: https://github.com/hiqdev/yii2-thememanager/commit/19cc7fa 407 | [a591721]: https://github.com/hiqdev/yii2-thememanager/commit/a591721 408 | [a812c8a]: https://github.com/hiqdev/yii2-thememanager/commit/a812c8a 409 | [051f14d]: https://github.com/hiqdev/yii2-thememanager/commit/051f14d 410 | [660e3eb]: https://github.com/hiqdev/yii2-thememanager/commit/660e3eb 411 | [dc48a87]: https://github.com/hiqdev/yii2-thememanager/commit/dc48a87 412 | [ae44253]: https://github.com/hiqdev/yii2-thememanager/commit/ae44253 413 | [4dc0217]: https://github.com/hiqdev/yii2-thememanager/commit/4dc0217 414 | [47b0aba]: https://github.com/hiqdev/yii2-thememanager/commit/47b0aba 415 | [489beb1]: https://github.com/hiqdev/yii2-thememanager/commit/489beb1 416 | [8040d38]: https://github.com/hiqdev/yii2-thememanager/commit/8040d38 417 | [0.3.1]: https://github.com/hiqdev/yii2-thememanager/compare/0.3.0...0.3.1 418 | [9b75f27]: https://github.com/hiqdev/yii2-thememanager/commit/9b75f27 419 | [364fdff]: https://github.com/hiqdev/yii2-thememanager/commit/364fdff 420 | [422a47b]: https://github.com/hiqdev/yii2-thememanager/commit/422a47b 421 | [7fcb548]: https://github.com/hiqdev/yii2-thememanager/commit/7fcb548 422 | [033c02d]: https://github.com/hiqdev/yii2-thememanager/commit/033c02d 423 | [f279ab0]: https://github.com/hiqdev/yii2-thememanager/commit/f279ab0 424 | [f2b73ec]: https://github.com/hiqdev/yii2-thememanager/commit/f2b73ec 425 | [968be6d]: https://github.com/hiqdev/yii2-thememanager/commit/968be6d 426 | [bdc23c2]: https://github.com/hiqdev/yii2-thememanager/commit/bdc23c2 427 | [cd4f3cb]: https://github.com/hiqdev/yii2-thememanager/commit/cd4f3cb 428 | [9a14757]: https://github.com/hiqdev/yii2-thememanager/commit/9a14757 429 | [76c23de]: https://github.com/hiqdev/yii2-thememanager/commit/76c23de 430 | [4cddce8]: https://github.com/hiqdev/yii2-thememanager/commit/4cddce8 431 | [85de120]: https://github.com/hiqdev/yii2-thememanager/commit/85de120 432 | [523ac50]: https://github.com/hiqdev/yii2-thememanager/commit/523ac50 433 | [f1ac15b]: https://github.com/hiqdev/yii2-thememanager/commit/f1ac15b 434 | [f994a12]: https://github.com/hiqdev/yii2-thememanager/commit/f994a12 435 | [0.3.2]: https://github.com/hiqdev/yii2-thememanager/compare/0.3.1...0.3.2 436 | [Development started]: https://github.com/hiqdev/yii2-thememanager/compare/dev...Development started 437 | [a01e793]: https://github.com/hiqdev/yii2-thememanager/commit/a01e793 438 | [7822e7e]: https://github.com/hiqdev/yii2-thememanager/commit/7822e7e 439 | [91d3d3f]: https://github.com/hiqdev/yii2-thememanager/commit/91d3d3f 440 | [c8603a0]: https://github.com/hiqdev/yii2-thememanager/commit/c8603a0 441 | [b3ad004]: https://github.com/hiqdev/yii2-thememanager/commit/b3ad004 442 | [3ccd8e5]: https://github.com/hiqdev/yii2-thememanager/commit/3ccd8e5 443 | [2ba8f11]: https://github.com/hiqdev/yii2-thememanager/commit/2ba8f11 444 | [4676742]: https://github.com/hiqdev/yii2-thememanager/commit/4676742 445 | [f557e68]: https://github.com/hiqdev/yii2-thememanager/commit/f557e68 446 | [63ce3b1]: https://github.com/hiqdev/yii2-thememanager/commit/63ce3b1 447 | [424d425]: https://github.com/hiqdev/yii2-thememanager/commit/424d425 448 | [0817fdd]: https://github.com/hiqdev/yii2-thememanager/commit/0817fdd 449 | [6137867]: https://github.com/hiqdev/yii2-thememanager/commit/6137867 450 | [0.4.0]: https://github.com/hiqdev/yii2-thememanager/compare/0.3.2...0.4.0 451 | [1b52083]: https://github.com/hiqdev/yii2-thememanager/commit/1b52083 452 | [8cf602a]: https://github.com/hiqdev/yii2-thememanager/commit/8cf602a 453 | [0.4.1]: https://github.com/hiqdev/yii2-thememanager/compare/0.4.0...0.4.1 454 | --------------------------------------------------------------------------------