Child Themify - Version 1.0

Version Description

  • Initial Release

=

Download this release

Release Info

Developer JohnPBloch
Plugin Icon wp plugin Child Themify
Version 1.0
Comparing to
See all releases

Version 1.0

Files changed (5) hide show
  1. child-themify.php +185 -0
  2. ctf.js +32 -0
  3. ctf.min.js +1 -0
  4. languages/child-themify.pot +60 -0
  5. readme.txt +41 -0
child-themify.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Plugin Name: Child Themify
4
+ * Description: Enables the quick creation of child themes from any non-child theme you have installed.
5
+ * Version: 1.0
6
+ * Plugin URI: https://github.com/johnpbloch/child-themify
7
+ * Author: John P. Bloch
8
+ * License: GPLv2 or later
9
+ */
10
+
11
+ class CTF_Babymaker {
12
+
13
+ /**
14
+ * Check the user's capabilities and validate the nonce
15
+ *
16
+ * Kills script execution if either of those tests fail
17
+ */
18
+ public static function getTested() {
19
+ $theme = empty( $_GET['theme'] ) ? '' : $_GET['theme'];
20
+ if ( !self::fertile() ) {
21
+ wp_die( __( 'You do not have permission to do that!', 'child-themify' ) );
22
+ }
23
+ check_admin_referer( self::nonce_name( $theme ), '_ctf_nonce' );
24
+ }
25
+
26
+ protected static function fertile() {
27
+ return current_user_can( 'install_themes' );
28
+ }
29
+
30
+ protected static function nonce( $theme ) {
31
+ return wp_create_nonce( self::nonce_name( $theme ) );
32
+ }
33
+
34
+ protected static function nonce_name( $theme ) {
35
+ return "child_themify_$theme";
36
+ }
37
+
38
+ public static function showInterface() {
39
+ $theme = empty( $_GET['theme'] ) ? '' : $_GET['theme'];
40
+ $theme = wp_get_theme( $theme );
41
+ if ( self::checkCreds() ) {
42
+ return;
43
+ }
44
+ settings_errors();
45
+ ?>
46
+ <div class="wrap">
47
+ <h2><?php echo esc_html( sprintf( _x( 'Create a child theme from %s', 'The placeholder is for a theme\'s name', 'child-themify' ), $theme->name ) ); ?></h2>
48
+ <form method="post" action="<?php echo esc_url( self::getLink( $theme->get_stylesheet() ) ); ?>">
49
+ <label><?php esc_html_e( 'Name your child theme', 'child-themify' ); ?></label><br>
50
+ <input type="text" name="new_theme" />
51
+ <?php submit_button( __( "Let's go!", 'child-themify' ) ); ?>
52
+ </form>
53
+ </div>
54
+ <?php
55
+ }
56
+
57
+ protected static function checkCreds() {
58
+ if ( empty( $_POST ) ) {
59
+ return false;
60
+ }
61
+ self::getTested();
62
+ $theme = empty( $_GET['theme'] ) ? '' : $_GET['theme'];
63
+ $theme = wp_get_theme( $theme );
64
+ $url = self::getLink( $theme );
65
+ if ( ($creds = request_filesystem_credentials( $url, '', false, get_theme_root(), array( 'new_theme' ) )) === false ) {
66
+ return true;
67
+ }
68
+ if ( !WP_Filesystem( $creds, get_theme_root() ) ) {
69
+ request_filesystem_credentials( $url, '', true, get_theme_root(), array( 'new_theme' ) );
70
+ return true;
71
+ }
72
+ self::procreate( $_POST['new_theme'], $theme );
73
+ }
74
+
75
+ /**
76
+ * Get the link to create a child theme from a theme
77
+ *
78
+ * @param string $theme_name The template theme's directory
79
+ * @return string The url to create a child theme
80
+ */
81
+ public static function getLink( $theme_name ) {
82
+ $theme = wp_get_theme( $theme_name );
83
+ // If the current user can't install a theme, the theme doesn't exist
84
+ if ( !self::fertile() || !$theme->exists() || $theme->parent() ) {
85
+ return '';
86
+ }
87
+ $args = array(
88
+ 'action' => 'child-themify',
89
+ 'theme' => $theme_name,
90
+ '_ctf_nonce' => self::nonce( $theme_name ),
91
+ );
92
+ $baseLink = is_multisite() ? network_admin_url( 'themes.php' ) : admin_url( 'themes.php' );
93
+ return add_query_arg( $args, $baseLink );
94
+ }
95
+
96
+ /**
97
+ * Add the link for creating a child theme to the theme action links
98
+ *
99
+ * @param array $links
100
+ * @param string|WP_Theme $theme
101
+ * @return array An array of action links
102
+ */
103
+ public static function moodLighting( array $links, $theme ) {
104
+ if ( !($theme instanceof WP_Theme) ) {
105
+ $theme = wp_get_theme( $theme );
106
+ }
107
+ if ( !self::fertile() || !$theme->exists() || $theme->parent() ) {
108
+ return $links;
109
+ }
110
+ $link = self::getLink( $theme->get_stylesheet() );
111
+ $html = sprintf( "<a href=\"$link\">%s</a>", __( 'Create a child theme', 'child-themify' ) );
112
+ $links['child-themify'] = $html;
113
+ return $links;
114
+ }
115
+
116
+ /**
117
+ * Runs the actual child theme creation functionality
118
+ *
119
+ * @global WP_Filesystem_Base $wp_filesystem
120
+ * @param string $new_theme
121
+ * @param WP_Theme $template
122
+ * @throws Exception If the global filesystem object isn't available
123
+ */
124
+ public static function procreate( $new_theme, WP_Theme $template ) {
125
+ global $wp_filesystem;
126
+ if ( !($wp_filesystem instanceof WP_Filesystem_Base) ) {
127
+ if ( !WP_Filesystem() ) {
128
+ throw new Exception( __( 'Could not access the filesystem!', 'child-themify' ) );
129
+ }
130
+ }
131
+ $oldStylesheet = $template->get_stylesheet();
132
+ $oldName = $template->name;
133
+ $new_theme_directory = trailingslashit( get_theme_root() ) . sanitize_file_name( strtolower( $new_theme ) );
134
+ $wp_filesystem->mkdir( $new_theme_directory );
135
+ $newStylesheet = trailingslashit( $new_theme_directory ) . 'style.css';
136
+ $wp_filesystem->touch( $newStylesheet );
137
+ $stylesheetContents = <<<EOF
138
+ /*
139
+ Theme Name: $new_theme
140
+ Version: 1.0
141
+ Description: A child theme of $oldName
142
+ Template: $oldStylesheet
143
+ */
144
+
145
+ @import url("../$oldStylesheet/style.css")
146
+
147
+ EOF;
148
+ $wp_filesystem->put_contents( $newStylesheet, $stylesheetContents );
149
+ add_settings_error( '', 'child-themify', __( 'Your child theme was created successfully.', 'child-themify' ), 'updated' );
150
+ }
151
+
152
+ public static function load_themes_page() {
153
+ if ( empty( $_GET['action'] ) || $_GET['action'] != 'child-themify' ) {
154
+ if ( !is_multisite() ) {
155
+ add_action( 'admin_footer', array( 'CTF_Babymaker', 'link_current_theme') );
156
+ }
157
+ return;
158
+ }
159
+ require ABSPATH . 'wp-admin/admin-header.php';
160
+ self::showInterface();
161
+ require ABSPATH . 'wp-admin/admin-footer.php';
162
+ exit;
163
+ }
164
+
165
+ public static function link_current_theme() {
166
+ $theme = wp_get_theme();
167
+ $link = self::getLink( $theme->get_stylesheet() );
168
+ $filename = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'ctf.js' : 'ctf.min.js';
169
+ wp_enqueue_script( 'child-themify', plugins_url( $filename, __FILE__ ), array(), '1.0', true );
170
+ wp_localize_script( 'child-themify', 'childThemify', array(
171
+ 'createAChildTheme' => __( 'Create a child theme', 'child-themify' ),
172
+ 'link' => $link,
173
+ ));
174
+ }
175
+
176
+ public static function init() {
177
+ load_plugin_textdomain( 'child-themify', false, basename( dirname( __FILE__ ) ) . '/languages' );
178
+ add_filter( 'theme_action_links', array( 'CTF_Babymaker', 'moodLighting' ), 10, 2 );
179
+ add_action( 'load-themes.php', array( 'CTF_Babymaker', 'load_themes_page' ) );
180
+ }
181
+
182
+ }
183
+
184
+ add_action( 'init', array( 'CTF_Babymaker', 'init' ) );
185
+
ctf.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function(l10n){
2
+ if ( typeof l10n.link !== 'string' || l10n.link.length < 1 ) {
3
+ return;
4
+ }
5
+ var themeOptions = document.getElementById('customize-current-theme-link'),
6
+ x,
7
+ optionsLinks,
8
+ newListItem,
9
+ newLink;
10
+ if ( themeOptions ) {
11
+ themeOptions = themeOptions.parentNode;
12
+ } else {
13
+ return;
14
+ }
15
+ for( x in themeOptions.childNodes ) {
16
+ if ( themeOptions.childNodes[x].nodeName !== undefined ) {
17
+ if ( themeOptions.childNodes[x].nodeName.toUpperCase() === 'UL' ) {
18
+ optionsLinks = themeOptions.childNodes[x];
19
+ break;
20
+ }
21
+ }
22
+ }
23
+ if ( !optionsLinks ) {
24
+ return;
25
+ }
26
+ newLink = document.createElement( 'a' );
27
+ newLink.appendChild( document.createTextNode( l10n.createAChildTheme ) );
28
+ newLink.href = l10n.link;
29
+ newListItem = document.createElement( 'li' );
30
+ newListItem.appendChild( newLink );
31
+ optionsLinks.appendChild( newListItem );
32
+ }(childThemify));
ctf.min.js ADDED
@@ -0,0 +1 @@
 
1
+ (function(e){if(typeof e.link!="string"||e.link.length<1)return;var t=document.getElementById("customize-current-theme-link"),n,r,i,s;if(!t)return;t=t.parentNode;for(n in t.childNodes)if(t.childNodes[n].nodeName!==undefined&&t.childNodes[n].nodeName.toUpperCase()==="UL"){r=t.childNodes[n];break}if(!r)return;s=document.createElement("a"),s.appendChild(document.createTextNode(e.createAChildTheme)),s.href=e.link,i=document.createElement("li"),i.appendChild(s),r.appendChild(i)})(childThemify);
languages/child-themify.pot ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2012 Child Themify
2
+ # This file is distributed under the same license as the Child Themify package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Child Themify 0.1-alpha\n"
6
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/child-themify\n"
7
+ "POT-Creation-Date: 2012-12-31 17:13:34+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2012-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+
15
+ #: child-themify.php:21
16
+ msgid "You do not have permission to do that!"
17
+ msgstr ""
18
+
19
+ #: child-themify.php:47
20
+ msgctxt "The placeholder is for a theme's name"
21
+ msgid "Create a child theme from %s"
22
+ msgstr ""
23
+
24
+ #: child-themify.php:49
25
+ msgid "Name your child theme"
26
+ msgstr ""
27
+
28
+ #: child-themify.php:51
29
+ msgid "Let's go!"
30
+ msgstr ""
31
+
32
+ #: child-themify.php:111 child-themify.php:171
33
+ msgid "Create a child theme"
34
+ msgstr ""
35
+
36
+ #: child-themify.php:128
37
+ msgid "Could not access the filesystem!"
38
+ msgstr ""
39
+
40
+ #: child-themify.php:149
41
+ msgid "Your child theme was created successfully."
42
+ msgstr ""
43
+
44
+ #. Plugin Name of the plugin/theme
45
+ msgid "Child Themify"
46
+ msgstr ""
47
+
48
+ #. Plugin URI of the plugin/theme
49
+ msgid "https://github.com/johnpbloch/child-themify"
50
+ msgstr ""
51
+
52
+ #. Description of the plugin/theme
53
+ msgid ""
54
+ "Enables the quick creation of child themes from any non-child theme you have "
55
+ "installed."
56
+ msgstr ""
57
+
58
+ #. Author of the plugin/theme
59
+ msgid "John P. Bloch"
60
+ msgstr ""
readme.txt ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Child Themify ===
2
+ Contributors: JohnPBloch
3
+ Tags: themes, child, theme
4
+ Requires at least: 3.4.2
5
+ Tested up to: 3.5
6
+ Stable tag: 1.0
7
+ License: GPLv2 or later
8
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+
10
+ Create child themes at the click of a button.
11
+
12
+ == Description ==
13
+
14
+ Create child themes from any non-child theme at the click of a button.
15
+
16
+ This plugin is multisite compatible; if used on a multisite network, controls for creating child themes will be in the network admin instead of the regular site admin.
17
+
18
+ == Installation ==
19
+
20
+ 1. Upload the `child-themify` directory and its contents to the `/wp-content/plugins/` directory (or your custom location if you manually changed the location).
21
+ 1. Activate the plugin through the 'Plugins' menu in WordPress
22
+ 1. You can now create a child theme of any non-child theme you have installed by going to the themes page and clicking "Create a child theme" from the actions links of the theme of your choice.
23
+
24
+ == Frequently Asked Questions ==
25
+
26
+ None yet.
27
+
28
+ == Screenshots ==
29
+
30
+ 1. Network administration area
31
+ 2. Single site administration area
32
+
33
+ == Changelog ==
34
+
35
+ = 1.0 =
36
+ * Initial Release
37
+
38
+ == Upgrade Notice ==
39
+
40
+ = 1.0 =
41
+ How are you seeing this?