├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── inc
└── ps-auto-loader.php
├── js
└── plugin-customizer-init.js
├── plugin-customizer-demo.php
├── readme.txt
├── src
├── Blank_Slate.php
├── Plugin_Customizer.php
├── Plugin_Customizer_Interface.php
└── assets
│ ├── js
│ ├── plugin-customizer-blank-slate.js
│ └── plugin-customizer-preview-templates.js
│ └── twentysixteen
│ ├── 404.php
│ ├── archive.php
│ ├── comments.php
│ ├── css
│ ├── editor-style.css
│ ├── ie.css
│ ├── ie7.css
│ └── ie8.css
│ ├── footer.php
│ ├── functions.php
│ ├── genericons
│ ├── COPYING.txt
│ ├── Genericons.eot
│ ├── Genericons.svg
│ ├── Genericons.ttf
│ ├── Genericons.woff
│ ├── LICENSE.txt
│ ├── README.md
│ └── genericons.css
│ ├── header.php
│ ├── image.php
│ ├── inc
│ ├── back-compat.php
│ ├── customizer.php
│ └── template-tags.php
│ ├── index.php
│ ├── js
│ ├── color-scheme-control.js
│ ├── customize-preview.js
│ ├── functions.js
│ ├── html5.js
│ ├── keyboard-image-navigation.js
│ └── skip-link-focus-fix.js
│ ├── page.php
│ ├── readme.txt
│ ├── rtl.css
│ ├── screenshot.png
│ ├── search.php
│ ├── searchform.php
│ ├── sidebar-content-bottom.php
│ ├── sidebar.php
│ ├── single.php
│ ├── style.css
│ └── template-parts
│ ├── biography.php
│ ├── content-none.php
│ ├── content-page.php
│ ├── content-search.php
│ ├── content-single.php
│ └── content.php
└── templates
├── content.php
├── newsletter.php
└── title.php
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Change Log
2 |
3 | ### 1.1.4 (2017/01/12 22:20 +00:00)
4 | - [1dc38fa](https://github.com/soderlind/plugin-customizer/commit/1dc38fa1aa217b7d0152bd9faf45e6110339f5d5) Version 1.1.4 (@soderlind)
5 | - [425dfa7](https://github.com/soderlind/plugin-customizer/commit/425dfa7e1bc3e925cdf21822841cc782f516baa6) Fix relative path to assets (@soderlind)
6 | - [0993f3f](https://github.com/soderlind/plugin-customizer/commit/0993f3fbdf8ab725caeb41faa8c034b6c2fa4d72) Fix comment (@soderlind)
7 | - [b1af8cd](https://github.com/soderlind/plugin-customizer/commit/b1af8cd8de1b06c55991e5bc259d2045a5a2eb23) Update changelog (@soderlind)
8 |
9 | ### 1.1.3 (2017/01/11 15:50 +00:00)
10 | - [7976ff1](https://github.com/soderlind/plugin-customizer/commit/7976ff18c04cead5e82729e970e45688f7fbb43a) Version 1.1.3 (@soderlind)
11 | - [6b566a6](https://github.com/soderlind/plugin-customizer/commit/6b566a634899bea33e9f3318c780dfda9c718060) Add comment (@soderlind)
12 | - [04f6cdc](https://github.com/soderlind/plugin-customizer/commit/04f6cdc3ee6b04cd66bef519e110c72dd5384b90) Add missing stylesheet_uri filter in change theme root (@soderlind)
13 | - [c09c437](https://github.com/soderlind/plugin-customizer/commit/c09c437c151e293394cc16a44da333fa4d65c557) Update code example (!!) (@soderlind)
14 | - [0d86b0c](https://github.com/soderlind/plugin-customizer/commit/0d86b0cecfd032aab6bd94c767ab078654c70c51) Update changelog (@soderlind)
15 |
16 | ### 1.1.2 (2017/01/09 19:09 +00:00)
17 | - [b06f606](https://github.com/soderlind/plugin-customizer/commit/b06f606914e8df69653ac835681a64c5fed6ad41) Version 1.1.2 (@soderlind)
18 | - [bff70e3](https://github.com/soderlind/plugin-customizer/commit/bff70e3bc5f1f2554d06b7af84e644758874a556) Add plugin description file for WordPress plugin repository (@soderlind)
19 | - [65738d2](https://github.com/soderlind/plugin-customizer/commit/65738d218c3a3ba90e5ecee1c0afdbc998932b48) Add deployment tools (@soderlind)
20 | - [f326601](https://github.com/soderlind/plugin-customizer/commit/f32660183916b785e182d8370c94859785c8c36a) Add plugin banner and icon (@soderlind)
21 | - [ed9b17b](https://github.com/soderlind/plugin-customizer/commit/ed9b17bf75a2b60e1f512f8cd5a968ebfaeb1e1d) Add missing change theme directory URI (@soderlind)
22 | - [959e1f4](https://github.com/soderlind/plugin-customizer/commit/959e1f4855b090a2a900e70b16b7e513b9e5e137) Minor bug fix (@soderlind)
23 | - [3853f52](https://github.com/soderlind/plugin-customizer/commit/3853f52b44a97ca3fe1f07fd7a82df035f5795e0) Update init code (@soderlind)
24 | - [9c8ebff](https://github.com/soderlind/plugin-customizer/commit/9c8ebff72b00fd01b50da5600a59320ccbb2b469) Remove unneeded code (@soderlind)
25 | - [1925001](https://github.com/soderlind/plugin-customizer/commit/1925001f96651452b61e6fa64d34772da3831a45) no message (@soderlind)
26 | - [47ae0c6](https://github.com/soderlind/plugin-customizer/commit/47ae0c6a4b76432ed0205cbbee0dae879190955b) Add CHANGELOG (@soderlind)
27 | - [aad5679](https://github.com/soderlind/plugin-customizer/commit/aad5679faef54a78244395ed714574863f8eefc4) exclude twentysixteen from rules check (@soderlind)
28 | - [bc549d4](https://github.com/soderlind/plugin-customizer/commit/bc549d4573fc00c5139b88c1ab0074309e50d0cd) Add link to download and example (@soderlind)
29 | - [fd01190](https://github.com/soderlind/plugin-customizer/commit/fd01190e62c1c4560fcd47202601bfff92457cd8) Add twentysixteen theme (@soderlind)
30 | - [4e0dc9d](https://github.com/soderlind/plugin-customizer/commit/4e0dc9d8d7e2d549218f01d5be055e1e71dc2ecd) Rewrite: (@soderlind)
31 | - [3078745](https://github.com/soderlind/plugin-customizer/commit/3078745c5f6bed5b3ddd0682ed444c1ed3a8d6c7) Add Interface (@soderlind)
32 | - [5f2a2e2](https://github.com/soderlind/plugin-customizer/commit/5f2a2e21afacd6e562de5f42a427ae85f1d19c6f) Update rules (@soderlind)
33 | - [3a2df95](https://github.com/soderlind/plugin-customizer/commit/3a2df9553cd7a26401a2682662845f6e29632143) Allow PSR-4 since I’m using an PSR-4 autoloader (@soderlind)
34 | - [1b745ee](https://github.com/soderlind/plugin-customizer/commit/1b745eefe4b32d5338627534a8bb0ac8e4f5558d) Rewrite code: (@soderlind)
35 | - [c7d54dd](https://github.com/soderlind/plugin-customizer/commit/c7d54ddc19ebfab92a318ffa119fd2d816fb2245) Add simple preview templates (@soderlind)
36 | - [be639aa](https://github.com/soderlind/plugin-customizer/commit/be639aab35a13226aab96e6fb4d0e9f86a5e5ca4) Update README with examples (@soderlind)
37 | - [9f5652e](https://github.com/soderlind/plugin-customizer/commit/9f5652e51e0162484f79af334e33f7256b75244d) Add autoloader (@soderlind)
38 | - [3012204](https://github.com/soderlind/plugin-customizer/commit/301220477d2c4e9714d589d0c632eb29f08f91ca) Add logo (@soderlind)
39 | - [924a458](https://github.com/soderlind/plugin-customizer/commit/924a4582e0dab9c32a6dc067ecfe737b000d339c) Rename and move file (@soderlind)
40 | - [11c279d](https://github.com/soderlind/plugin-customizer/commit/11c279d2c7c90619ce2ea5871bb27da239703f63) Merge branch 'master' of https://github.com/soderlind/plugin-customizer (@soderlind)
41 | - [0fd7bb2](https://github.com/soderlind/plugin-customizer/commit/0fd7bb2875537d153615ef3b35afc0a13a453f8c) Add JavaScript rules (@soderlind)
42 | - [80af3a6](https://github.com/soderlind/plugin-customizer/commit/80af3a6b93eae75be1969ca52c02c58eae682055) Abstract class, rename file (@soderlind)
43 | - [0b270fb](https://github.com/soderlind/plugin-customizer/commit/0b270fbd1ae5475940c5f9d9880fa58cdcd09c25) Update code according to WPCS (@soderlind)
44 | - [5bcc2cb](https://github.com/soderlind/plugin-customizer/commit/5bcc2cb51c1a6ebe9ad65baf476e89fd90b0e4b5) Rename file (@soderlind)
45 | - [0457dde](https://github.com/soderlind/plugin-customizer/commit/0457dde4c02f65f08573f7c815657c7b7377030d) Update README.md (@soderlind)
46 | - [ad49d80](https://github.com/soderlind/plugin-customizer/commit/ad49d805a8b2bbdbea7f2fe02e14db7ca66d4cdd) Update README.md (@soderlind)
47 | - [d8cb6c7](https://github.com/soderlind/plugin-customizer/commit/d8cb6c77248696110291ec3c18c3d5d946528ee5) Add notice about bug in Twenty Seventeen (@soderlind)
48 | - [a071b81](https://github.com/soderlind/plugin-customizer/commit/a071b8158c819b3c49ea68284b2b5ddadfbcc9c0) Add copyright and license information (@soderlind)
49 | - [a809cca](https://github.com/soderlind/plugin-customizer/commit/a809cca95e2239e92aaee98647004c08ebc98241) Add source example (@soderlind)
50 | - [482465a](https://github.com/soderlind/plugin-customizer/commit/482465a5e7972d7eb278e884d114ad137b15ec4e) Add travis and codeclimate badge (@soderlind)
51 | - [508d458](https://github.com/soderlind/plugin-customizer/commit/508d4580594e1b25328eeec3c663bd469e16d5f1) Add travis config file (@soderlind)
52 | - [c22380a](https://github.com/soderlind/plugin-customizer/commit/c22380a61b4bc93429c62192d7d76a95b640d7b9) Update comments (@soderlind)
53 | - [e88cc4d](https://github.com/soderlind/plugin-customizer/commit/e88cc4d7cc6076fc0b03bfc66393fa829316967b) Add link to article (@soderlind)
54 | - [a141eec](https://github.com/soderlind/plugin-customizer/commit/a141eec245d16ae9d6d1194f6d0e38b82b26c02a) Add "How to contribute" (@soderlind)
55 | - [8dd5a3f](https://github.com/soderlind/plugin-customizer/commit/8dd5a3f66b2da0ba35a9bd8881fb35c212bab4b6) Fix timings, add comments (@soderlind)
56 | - [f1f2b5d](https://github.com/soderlind/plugin-customizer/commit/f1f2b5df7ec6b6b44ee0c3253f91a3f04fe1f4c3) Add update preview script (@soderlind)
57 | - [7ddf48d](https://github.com/soderlind/plugin-customizer/commit/7ddf48dfa3aba55655eba324ab910b84096b08cf) Add get_option() to templates (@soderlind)
58 | - [cb6a19d](https://github.com/soderlind/plugin-customizer/commit/cb6a19d9c18e468c8564c7f5c0adebb1b3648b9e) Rename script (@soderlind)
59 | - [61017e5](https://github.com/soderlind/plugin-customizer/commit/61017e5a1e1b0ab2de60bce3b8aece03a78ea078) Add example option page (@soderlind)
60 | - [16aea5b](https://github.com/soderlind/plugin-customizer/commit/16aea5b5fc4163df092f7c4f474c2e2386ec00eb) Change args.panel to args.id (@soderlind)
61 | - [c54c45a](https://github.com/soderlind/plugin-customizer/commit/c54c45ae760e4a7e8bf99bdd0e7497472e946895) Add customizer clean slate (@soderlind)
62 | - [f3c6fb1](https://github.com/soderlind/plugin-customizer/commit/f3c6fb1f7ab210e8d9a54f3de8a7e1dd99db4ad2) Rename template (@soderlind)
63 | - [8a82343](https://github.com/soderlind/plugin-customizer/commit/8a8234354c3bc1f9a911fec2d9eb6bf0b63d5471) remove obsolete files (@soderlind)
64 | - [c0fba2d](https://github.com/soderlind/plugin-customizer/commit/c0fba2d716727e4692111bb2c20b4a685807f513) Add customizer blank slate (@soderlind)
65 | - [e663236](https://github.com/soderlind/plugin-customizer/commit/e6632364d9d686dda702149d97dd25364a87f71c) Add preview template (@soderlind)
66 | - [4955a6b](https://github.com/soderlind/plugin-customizer/commit/4955a6b3bb50fe8ad79e6f415d294838370b9ee6) Add permalink (@soderlind)
67 | - [0e4e622](https://github.com/soderlind/plugin-customizer/commit/0e4e622b82ab498712ea04012c4b04c177abd291) Change: Load on panel change (@soderlind)
68 | - [d3ae0c8](https://github.com/soderlind/plugin-customizer/commit/d3ae0c8c1a47b09137df65ab1a59b3c8cecabbc8) Add template loader (@soderlind)
69 | - [c597d44](https://github.com/soderlind/plugin-customizer/commit/c597d445e6ed7dc2a87bacaf21ff5bc089f00664) Delete obsolete files (@soderlind)
70 | - [a4ea6b8](https://github.com/soderlind/plugin-customizer/commit/a4ea6b8be19847e93009409214d55f9a095a40b7) Add code climate config files (@soderlind)
71 | - [da9bbdf](https://github.com/soderlind/plugin-customizer/commit/da9bbdfb3afbc18d638b89a7d2cda31608d0a42c) add customizer preview (@soderlind)
72 | - [4373e39](https://github.com/soderlind/plugin-customizer/commit/4373e39b68567da71e87e2ebf6a34e870164c780) Add args for adding url and section (@soderlind)
73 | - [0e855b4](https://github.com/soderlind/plugin-customizer/commit/0e855b4b4ec7b365244b01a92fcd3d8cc7aac476) working demo (@soderlind)
74 | - [7c74c27](https://github.com/soderlind/plugin-customizer/commit/7c74c272f22b89f35b5a98a571421dbf79eb9fb1) Merge branch 'master' of https://github.com/soderlind/plugin-customizer (@soderlind)
75 | - [9ed2b58](https://github.com/soderlind/plugin-customizer/commit/9ed2b5802333cb75a894ccef836a91f85f21f1f4) Initial release (@soderlind)
76 | - [4e031e8](https://github.com/soderlind/plugin-customizer/commit/4e031e8b0ae9168cfe14c05130b0fd26d98e118c) Initial commit (@soderlind)
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | I'm really glad you're reading this.
4 |
5 | ## Submitting changes
6 |
7 | Please send a [GitHub Pull Request to plugin-customizer](https://github.com/soderlind/plugin-customizer/pull/new/master) with a clear list of what you've done (read more about [pull requests](http://help.github.com/pull-requests/)).
8 | Always write a clear log message for your commits. One-line messages are fine for small changes, but bigger changes should look like this:
9 |
10 | $ git commit -m "A brief summary of the commit
11 | >
12 | > A paragraph describing what changed and its impact."
13 |
14 | ## Coding conventions
15 |
16 | My plugins are following the [WordPress Coding Standards](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards).
17 |
18 | Thanks,
19 | Per Søderlind
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Plugin Customizer
4 |
Nulla laoreet erat vitae aliquet tristique. Quisque quis suscipit enim, a elementum eros. Vestibulum quis lacus ligula. Mauris sit amet nibh tincidunt, gravida tortor ac, maximus nisi. Nunc turpis mauris, blandit vitae nibh non, blandit pharetra purus. Sed sed convallis diam. In ante nisi, pellentesque in laoreet at, fringilla ac neque.
Cras consequat eros lectus, ac dignissim justo cursus ac. In mi tortor, ornare eu quam a, ultrices tincidunt magna. Fusce non purus quis ex convallis vehicula. Aenean purus diam, vulputate vel pellentesque ultrices, tincidunt ac lectus. Nullam est purus, lobortis ac aliquam eget, egestas a diam. Praesent eget sapien vitae orci faucibus tempus. Ut sit amet lorem elit. Curabitur et vestibulum nibh.
Mauris vestibulum eget nisl sit amet gravida. Nullam in orci ut sem maximus dapibus blandit quis dolor. Sed pretium efficitur elit, eget vulputate sapien bibendum non. Proin congue posuere sagittis. Ut fermentum mauris ut gravida faucibus. Aenean a malesuada magna. Vestibulum nec viverra metus. Nunc aliquam eros orci, ut malesuada felis malesuada vitae. Phasellus vehicula non ex at scelerisque.
' ), 154 | ) 155 | ); 156 | return true; 157 | } 158 | 159 | /** 160 | * Add contronls. 161 | * 162 | * @author soderlind 163 | * @version 1.0.0 164 | * @param WP_Customize_Manager $wp_customize 165 | */ 166 | public function customizer_plugin_controls( $wp_customize ) { 167 | global $wp_customize; 168 | 169 | $wp_customize->add_control( new WP_Customize_Control( 170 | $wp_customize, 171 | 'newsletter_title', 172 | array( 173 | 'label' => __( 'Title', 'plugin-customizer' ), 174 | 'type' => 'text', 175 | 'section' => 'newsletter_title_section', 176 | 'settings' => 'newsletter_title', 177 | ) 178 | ) ); 179 | 180 | $wp_customize->add_control( new WP_Customize_Control( 181 | $wp_customize, 182 | 'newsletter_content', 183 | array( 184 | 'label' => __( 'Content', 'plugin-customizer' ), 185 | 'section' => 'newsletter_content_section', 186 | 'settings' => 'newsletter_content', 187 | 'type' => 'textarea', 188 | ) 189 | ) ); 190 | return true; 191 | } 192 | 193 | /** 194 | * Admin menus 195 | */ 196 | 197 | public function add_admin_menus() { 198 | /** 199 | * Add admin menu, You'll most likely only need one of them. 200 | */ 201 | 202 | // root menu 203 | add_action( 'admin_menu', array( $this, 'register_root_menu' ) ); 204 | add_action( 'admin_init', array( $this, 'root_menu_redirect_to_customizer' ) , 1 ); 205 | // submenu 206 | add_action( 'admin_menu', array( $this, 'register_sub_menu' ) ); 207 | // admin bar 208 | add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_customizer_url' ), 500 ); 209 | // admin options page 210 | add_action( 'admin_menu', array( $this, 'add_option_page' ) ); 211 | add_action( 'admin_init', array( $this, 'settings_init' ) ); 212 | 213 | } 214 | 215 | /** 216 | * Create top level (root) menu. Will create URL with parameter page=redirect-customizer 217 | * 218 | * @author soderlind 219 | * @version 1.0.0 220 | */ 221 | public function register_root_menu() { 222 | add_menu_page( 223 | __( 'Plugin Customizer', 'plugin-customizer' ), 224 | __( 'Plugin Customizer', 'plugin-customizer' ), 225 | 'manage_options', 226 | 'redirect-customizer', 227 | 'function' 228 | ); 229 | } 230 | 231 | /** 232 | * Redirect to customizer url 233 | * 234 | * See http://wordpress.stackexchange.com/a/175574/14546 235 | * @author soderlind 236 | * @version 1.0.0 237 | */ 238 | function root_menu_redirect_to_customizer() { 239 | $menu_redirect = isset( $_GET['page'] ) ? $_GET['page'] : false; 240 | 241 | if ( 'redirect-customizer' == $menu_redirect ) { 242 | wp_safe_redirect( \PluginCustomizer\Plugin_Customizer::get_customizer_url( admin_url() ) ); 243 | exit(); 244 | } 245 | } 246 | 247 | /** 248 | * Create submenu 249 | * @author soderlind 250 | * @version 1.0.0 251 | */ 252 | public function register_sub_menu() { 253 | add_options_page( 254 | __( 'Plugin Customizer', 'plugin-customizer' ), 255 | __( 'Plugin Customizer', 'plugin-customizer' ), 256 | 'manage_options', 257 | 'plugin-template', 258 | '__return_null' 259 | ); 260 | $this->add_sub_menu_customizer_url(); 261 | } 262 | 263 | /** 264 | * Replace the 'plugin-template' string, in the submenu added by register_sub_menu(), 265 | * with the customizer url. 266 | * 267 | * See http://wordpress.stackexchange.com/a/131214/14546 268 | * 269 | * @author soderlind 270 | * @version 1.0.0 271 | */ 272 | function add_sub_menu_customizer_url( $parent = 'options-general.php' ) { 273 | global $submenu; 274 | 275 | if ( ! isset( $submenu[ $parent ] ) ) { 276 | return; 277 | } 278 | foreach ( $submenu[ $parent ] as $k => $d ) { 279 | if ( 'plugin-template' == $d['2'] ) { 280 | $submenu[ $parent ][ $k ]['2'] = \PluginCustomizer\Plugin_Customizer::get_customizer_url( $parent ); 281 | break; 282 | } 283 | } 284 | } 285 | 286 | /** 287 | * [add_admin_bar_customizer_url description] 288 | * @author soderlind 289 | * @version 1.0.0 290 | * @param [type] $wp_admin_bar [description] 291 | */ 292 | function add_admin_bar_customizer_url( $wp_admin_bar ) { 293 | global $post; 294 | if ( is_admin() ) { 295 | $return_url = $this->_get_current_admin_page_url(); 296 | } elseif ( is_object( $post ) ) { 297 | $return_url = get_permalink( $post->ID ); 298 | } else { 299 | $return_url = esc_url( home_url( '/' ) ); 300 | } 301 | 302 | $args = array( 303 | 'id' => 'plugin-customizer-link', 304 | 'title' => __( 'Plugin Customizer', 'plugin-customizer' ), 305 | 'href' => \PluginCustomizer\Plugin_Customizer::get_customizer_url( $return_url ), 306 | ); 307 | 308 | $wp_admin_bar->add_node( $args ); 309 | } 310 | 311 | /** 312 | * Find the current admin url. 313 | * 314 | * From: https://core.trac.wordpress.org/ticket/27888 315 | * 316 | * @author soderlind 317 | * @version 1.0.0 318 | * @return String|Bool The URL to the current admin page, or false if not in wp-admin. 319 | */ 320 | private function _get_current_admin_page_url() { 321 | if ( ! is_admin() ) { 322 | return false; 323 | } 324 | global $pagenow; 325 | 326 | $url = $pagenow; 327 | $query_string = $_SERVER['QUERY_STRING']; 328 | 329 | if ( ! empty( $query_string ) ) { 330 | $url .= '?' . $query_string; 331 | } 332 | return $url; 333 | } 334 | 335 | /** 336 | * Add an example option page. 337 | * @author soderlind 338 | * @version 1.0.0 339 | */ 340 | public function add_option_page() { 341 | add_menu_page( 'Plugin Customizer Options', 'Plugin Customizer Options', 'manage_options', 'plugin-customizer', array( $this, 'options_page' ) ); 342 | } 343 | 344 | public function settings_init() { 345 | register_setting( 'pluginPage', 'settings' ); 346 | add_settings_section( 'pluginPage_section', __( 'Demonstrate how to load the customizer from an option page', 'plugin-customizer' ), '', 'pluginPage' ); 347 | add_settings_field( 'option_page_customizer', __( 'Open customizer ', 'plugin-customizer' ), array( $this, 'option_page_customizer_link' ), 'pluginPage', 'pluginPage_section' ); 348 | } 349 | 350 | public function option_page_customizer_link() { 351 | printf( '%s%s
', 352 | \PluginCustomizer\Plugin_Customizer::get_customizer_url( 'admin.php?page=plugin-customizer', 'newsletter_title_section' ), __( 'Customize', 'plugin-customizer' ), 353 | __( 'Will use autofocus[section]=newletter_title to focus on the title (eg open it)', 'plugin-customizer' ) 354 | ); 355 | } 356 | 357 | public function options_page() { 358 | ?> 359 | 368 | Add New` 22 | 1. Search for `Plugin Customizer` 23 | 1. Install and Activate 24 | 25 | or 26 | 27 | 1. Download the plugin and extract the plugin-customizer.zip 28 | 1. Upload the extracted `plugin-customizer` folder to the `/wp-content/plugins/` directory 29 | 1. Activate the plugin through the 'Plugins' menu in WordPress 30 | 31 | The plugin is also [available at GitHub](https://github.com/soderlind/plugin-customizer) 32 | 33 | == Changelog == 34 | 35 | = 1.1.2 = 36 | * Initial release. 37 | -------------------------------------------------------------------------------- /src/Blank_Slate.php: -------------------------------------------------------------------------------- 1 | slug = $slug; 41 | $this->plugin_url = $plugin_url; 42 | $this->plugin_root = $plugin_root; 43 | add_filter( 'customize_loaded_components', function() { 44 | 45 | $priority = 1; 46 | add_action( 'wp_loaded', function() { 47 | 48 | global $wp_customize; 49 | remove_all_actions( 'customize_register' ); 50 | $wp_customize->register_panel_type( 'WP_Customize_Panel' ); 51 | $wp_customize->register_section_type( 'WP_Customize_Section' ); 52 | $wp_customize->register_section_type( 'WP_Customize_Sidebar_Section' ); 53 | $wp_customize->register_control_type( 'WP_Customize_Color_Control' ); 54 | $wp_customize->register_control_type( 'WP_Customize_Media_Control' ); 55 | $wp_customize->register_control_type( 'WP_Customize_Upload_Control' ); 56 | $wp_customize->register_control_type( 'WP_Customize_Image_Control' ); 57 | $wp_customize->register_control_type( 'WP_Customize_Background_Image_Control' ); 58 | $wp_customize->register_control_type( 'WP_Customize_Cropped_Image_Control' ); 59 | $wp_customize->register_control_type( 'WP_Customize_Site_Icon_Control' ); 60 | $wp_customize->register_control_type( 'WP_Customize_Theme_Control' ); 61 | }, $priority ); 62 | $components = array(); 63 | 64 | return $components; 65 | } ); 66 | add_action( 'customize_controls_init', function() { 67 | global $wp_customize; 68 | $wp_customize->set_preview_url( 69 | add_query_arg( 70 | array( $this->slug => 'on' ), 71 | $wp_customize->get_preview_url() 72 | ) 73 | ); 74 | } ); 75 | 76 | add_action( 'customize_controls_enqueue_scripts', function() { 77 | $handle = 'plugin-customizer-blank-slate'; 78 | $src = $this->plugin_url . 'assets/js/plugin-customizer-blank-slate.js'; 79 | $deps = array( 'customize-controls' ); 80 | $ver = false; 81 | $in_footer = true; 82 | wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer ); 83 | 84 | $args = array( 85 | 'queryParamName' => $this->slug, 86 | 'queryParamValue' => 'on', 87 | ); 88 | wp_add_inline_script( 89 | $handle, 90 | sprintf( 'PluginCustomizerBlankSlate.init( %s );', wp_json_encode( $args ) ), 91 | 'after' 92 | ); 93 | } ); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Plugin_Customizer.php: -------------------------------------------------------------------------------- 1 | 'Plugin Customizer', 45 | 'url' => plugins_url( '', dirname( __FILE__ ) ), 46 | 'path' => plugin_dir_path( dirname( __FILE__ ) ), 47 | ) ); 48 | 49 | $this->slug = sanitize_title( $config['name'] , 'plugin-customizer' ); 50 | $this->plugin_name = $config['name']; 51 | $this->plugin_url = $config['url']; 52 | $this->plugin_root = $config['path']; 53 | $this->url = plugins_url( '/', __FILE__ ); 54 | $this->root = plugin_dir_path( __FILE__ ); 55 | 56 | /** 57 | * When saving the setinngs, the customizer settings must be visible for admin-ajax.php 58 | * so add it before the bailout test. 59 | */ 60 | add_action( 'wp_loaded', function() { 61 | add_action( 'customize_register', array( $this, 'customizer_plugin_settings' ) ); 62 | }, $this->customize_register_priority ); 63 | /** 64 | * Bailout if not called from the plugin menu links. 65 | */ 66 | if ( ! isset( $_GET[ $this->slug ] ) || 'on' !== wp_unslash( $_GET[ $this->slug ] ) ) { 67 | return; 68 | } 69 | /** 70 | * Set the customizer title. 71 | */ 72 | add_filter( 'pre_option_blogname', function(){ 73 | return $this->plugin_name; 74 | } ); 75 | 76 | /** 77 | * WordPres Customizer is dependant on functionality in the theme. Just in case 78 | * the current theme doesn't support WordPress Customizer we'll use a theme 79 | * that supports it. 80 | */ 81 | add_action( 'setup_theme', function() { 82 | add_filter( 'theme_root', array( $this, 'switch_theme_root_path' ) ); 83 | add_filter( 'template_directory_uri', array( $this, 'switch_template_uri' ) ); 84 | add_filter( 'stylesheet_uri', array( $this, 'switch_template_uri' ) ); 85 | add_filter( 'pre_option_stylesheet', function(){ 86 | return $this->theme_name; 87 | } ); 88 | add_filter( 'pre_option_template', function(){ 89 | return $this->theme_name; 90 | } ); 91 | } ); 92 | /** 93 | * Remove all other panels and sections from the customizer. 94 | */ 95 | $blank_slate = Blank_Slate::instance(); 96 | $blank_slate->init( $this->slug, $this->url, $this->root ); 97 | 98 | /** 99 | * Create preview template permalink rules. 100 | * Also see plugin_customizer_configure_previewer(), template_loader() and js/plugin-customizer-preview-templates.js 101 | * 102 | * A 'how to create permalink' tutorial is at https://soderlind.no/wordpress-plugins-and-permalinks-how-to-use-pretty-links-in-your-plugin/ 103 | */ 104 | add_filter( 'generate_rewrite_rules', array( $this, 'rewrite_rule' ) ); 105 | add_filter( 'query_vars', array( $this, 'query_vars' ) ); 106 | add_filter( 'admin_init', array( $this, 'flush_rewrite_rules' ) ); 107 | 108 | /** 109 | * Parse request from js/plugin-customizer-preview-templates.js previewer script and load the template. 110 | */ 111 | add_action( 'parse_request', array( $this, 'template_loader' ) ); 112 | 113 | /** 114 | * Enqueue previewer script. 115 | * 116 | * See https://make.xwp.co/2016/07/21/navigating-to-a-url-in-the-customizer-preview-when-a-section-is-expanded/ 117 | */ 118 | add_action( 'customize_controls_enqueue_scripts', array( $this, 'plugin_customizer_configure_previewer' ) ); 119 | add_action( 'customize_controls_enqueue_scripts', array( $this, 'plugin_customizer_add_templates' ), 11 ); 120 | 121 | /** 122 | * The plugin is using transport => postMessage, set in customizer_plugin_settings(), and needs 123 | * javascript to update the preview. 124 | * 125 | * You can Learn more about postmessage at: 126 | * https://developer.wordpress.org/themes/advanced-topics/customizer-api/#using-postmessage-for-improved-setting-previewing 127 | */ 128 | add_action( 'customize_preview_init', array( $this, 'plugin_customizer_previewer_postmessage_script' ) ); 129 | /** 130 | * Register plugin customizer settings. 131 | */ 132 | add_action( 'wp_loaded', function() { 133 | add_action( 'customize_register', array( $this, 'customizer_plugin_sections' ) ); 134 | add_action( 'customize_register', array( $this, 'customizer_plugin_controls' ) ); 135 | 136 | /** 137 | * If you plan to use selective refresh, set the transport in customizer_plugin_settings() 138 | * to 'refresh' and uncomment the line below. Also comment out the customize_preview_init action above. 139 | * 140 | * You can learn more about selective refresh at: 141 | * https://make.wordpress.org/core/2016/02/16/selective-refresh-in-the-customizer/ 142 | */ 143 | // add_action( 'customize_register', array( $this, 'customizer_plugin_selective_refresh' ) ); 144 | }, $this->customize_register_priority ); 145 | 146 | } 147 | 148 | /** 149 | * Create rewrite rule for the template URL used by js/plugin-cusomizer-scripts.js 150 | * 151 | * See: https://soderlind.no/wordpress-plugins-and-permalinks-how-to-use-pretty-links-in-your-plugin/ 152 | * 153 | * @author soderlind 154 | * @version 1.0.0 155 | * @param Object $wp_rewrite Permalink structure 156 | * @return Array Rewrite rules 157 | */ 158 | function rewrite_rule( $wp_rewrite ) { 159 | $new_rules = array( 160 | sprintf( '%s/templates/(.*)$', $this->slug ) => sprintf( 'index.php?plugin-customizer-template-%s=%s', $this->slug, $wp_rewrite->preg_index( 1 ) ), 161 | ); 162 | 163 | $wp_rewrite->rules = $new_rules + $wp_rewrite->rules; 164 | return $wp_rewrite->rules; 165 | } 166 | 167 | /** 168 | * Add query variable for the rewrite rule used by the template URL 169 | * 170 | * See: https://soderlind.no/wordpress-plugins-and-permalinks-how-to-use-pretty-links-in-your-plugin/ 171 | * 172 | * @author soderlind 173 | * @version 1.0.0 174 | * @param Array $query_vars All defined query variables. 175 | * @return Array The updated array with query variables. 176 | */ 177 | function query_vars( $query_vars ) { 178 | $query_vars[] = sprintf( 'plugin-customizer-template-%s', $this->slug ); 179 | return $query_vars; 180 | } 181 | 182 | /** 183 | * Flush the permalink structure. 184 | * 185 | * See: https://soderlind.no/wordpress-plugins-and-permalinks-how-to-use-pretty-links-in-your-plugin/ 186 | * 187 | * @author soderlind 188 | * @version 1.0.0 189 | */ 190 | function flush_rewrite_rules() { 191 | $rules = $GLOBALS['wp_rewrite']->wp_rewrite_rules(); 192 | if ( ! isset( $rules[ sprintf( '%s/templates/(.*)$', $this->slug ) ] ) ) { // must be the same rule as in rewrite_rule($wp_rewrite) 193 | global $wp_rewrite; 194 | $wp_rewrite->flush_rules(); 195 | } 196 | } 197 | 198 | /** 199 | * Create the preview. 200 | * 201 | * The WordPress customizer uses ajax to communicate with the preview. To load the needed 202 | * scripts, wp_head() and wp_footer() must be added to the template. 203 | * 204 | * @author soderlind 205 | * @version 1.0.0 206 | */ 207 | function template_loader( $wp_query ) { 208 | $key = sprintf( 'plugin-customizer-template-%s', $this->slug ); 209 | if ( isset( $wp_query->query_vars[ $key ] ) ) { // same as the first custom variable in query_vars( $query_vars ) 210 | $template = $wp_query->query_vars[ $key ] . '.php'; 211 | wp_head(); 212 | $this->_load_template( $template ); 213 | wp_footer(); 214 | 215 | exit( 0 ); 216 | } 217 | } 218 | 219 | /** 220 | * Load the themplate and display the template if found 221 | * 222 | * Will try to locate the template in this order: 223 | * 1) [child-theme]/plugin-customizer/ 224 | * 2) [parent-theme]/plugin-customizer/ 225 | * 3) [plugin directory]/templates/ 226 | * 227 | * @author soderlind 228 | * @version 1.0.0 229 | * @param string $template plugin_root to the template 230 | */ 231 | private function _load_template( $template ) { 232 | // from: https://developer.wordpress.org/reference/functions/load_template/#comment-727 233 | if ( $overridden_template = locate_template( "plugin-customizer/{$template}" ) ) { 234 | /* 235 | * locate_template() returns plugin_root to file. 236 | * if either the child theme or the parent theme have overridden the template, load it. 237 | */ 238 | load_template( $overridden_template ); 239 | } else { 240 | /* 241 | * If neither the child nor parent theme have overridden the template, 242 | * we load the template from the 'templates' sub-directory of the directory this file is in. 243 | */ 244 | load_template( $this->plugin_root . "templates/{$template}" ); 245 | } 246 | } 247 | /** 248 | * Load the previewer script and pass the template URL as argument to the script. 249 | * Optionally load separate templates for the customizer sections. 250 | * 251 | * @author soderlind 252 | * @version 1.0.0 253 | */ 254 | public function plugin_customizer_configure_previewer() { 255 | $src = $this->url . 'assets/js/plugin-customizer-preview-templates.js'; 256 | $deps = array( 'customize-controls' ); 257 | $version = PLUGIN_CUSTOMIZER_VERSION; 258 | $in_footer = 1; 259 | wp_enqueue_script( $this->slug, $src, $deps, $version , $in_footer ); 260 | } 261 | 262 | abstract public function plugin_customizer_add_templates(); 263 | 264 | public function template_url( $template ) { 265 | $template = basename( $template, '.php' ); 266 | $template_url = home_url( sprintf( '%s/templates/%s/?%s=on', $this->slug, $template, $this->slug ) ); 267 | 268 | return $template_url; 269 | } 270 | 271 | public function add_templates( $default_url, $section_urls = array() ) { 272 | wp_add_inline_script( 273 | $this->slug, 274 | sprintf( 'PluginCustomizer.init( %s, %s );', 275 | wp_json_encode( $default_url ), 276 | wp_json_encode( $section_urls ) 277 | ), 278 | 'after' 279 | ); 280 | } 281 | 282 | /** 283 | * Load the preview script. The script is needed sice the transport is postmessage 284 | * @author soderlind 285 | * @version 1.0.0 286 | */ 287 | abstract public function plugin_customizer_previewer_postmessage_script(); 288 | 289 | /** 290 | * Create the customizer URL. 291 | * 292 | * @author soderlind 293 | * @version 1.0.0 294 | * @param string $return_url The URL to return to when closing the customizer. 295 | * @param string $autofocus_section Used for deep-linking, i.e. this section will be selected 296 | * when the customizer is opened. 297 | * @return string The customizer URL. 298 | */ 299 | protected function get_customizer_url( $return_url = '', $autofocus_section = '' ) { 300 | // If no return url, set the return url to the main admin url. 301 | if ( '' == $return_url ) { 302 | $return_url = admin_url(); 303 | } 304 | $url = wp_customize_url(); 305 | // Add parameter to identify this as a customizer url for this plugin. 306 | $url = add_query_arg( $this->slug , 'on', $url ); 307 | // If autofocus, add parameter to url. 308 | if ( '' !== $autofocus_section ) { 309 | $url = add_query_arg( 'autofocus[section]', $autofocus_section, $url ); 310 | } 311 | //Add parameter for return url. 312 | $url = add_query_arg( 'return', urlencode( $return_url ), $url ); 313 | //Sanitize url. 314 | $url = esc_url_raw( $url ); 315 | return $url; 316 | } 317 | 318 | 319 | abstract public function customizer_plugin_sections( $wp_customize ); 320 | abstract public function customizer_plugin_settings( $wp_customize ); 321 | abstract public function customizer_plugin_controls( $wp_customize ); 322 | 323 | // inspired by https://gist.github.com/franz-josef-kaiser/8608140 324 | public function switch_theme_root_path( $org_theme_root ) { 325 | $crrent_theme = wp_get_theme( $this->theme_name ); 326 | // if theme exists, no point in changing theme root. 327 | if ( $crrent_theme->exists() ) { 328 | return $org_theme_root; 329 | } 330 | 331 | $new_theme_root = $this->root . 'assets'; 332 | # Too early to use register_theme_directory() 333 | if ( ! in_array( $new_theme_root, $GLOBALS['wp_theme_directories'] ) ) { 334 | $GLOBALS['wp_theme_directories'][] = $new_theme_root; 335 | } 336 | 337 | return $new_theme_root; 338 | } 339 | 340 | public function switch_template_uri( $uri ) { 341 | $new_theme_root_uri = $this->url . 'assets/' . $this->theme_name; 342 | return $new_theme_root_uri; 343 | } 344 | 345 | public function plugin_theme_name() { 346 | return $this->theme_name; 347 | } 348 | } 349 | } 350 | -------------------------------------------------------------------------------- /src/Plugin_Customizer_Interface.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
27 | 47 |
48 | 49 | 50 | 51 |52 | 'ol', 55 | 'short_ping' => true, 56 | 'avatar_size' => 42, 57 | ) ); 58 | ?> 59 |
60 | 61 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | '', 75 | 'title_reply_after' => '
', 76 | ) ); 77 | ?> 78 | 79 |