This looks like a feature discussion now! O:-)
Yes, a "create new variant" could be a useful thing to have, but before having it, the variants of a theme have to be removed from index.template.php and sent to... the database I guess.
Good news and I like. It will be simpler and easier to those who don't want to theme everything up.
Currently this can be implemented via some ugly coding which is as follows.
1. In ManageThemes.controller.php, find:
// Look for a non existent theme directory. (ie theme87.)
$theme_dir = BOARDDIR . '/themes/theme';
$i = 1;
while (file_exists($theme_dir . $i))
$i++;
$context['new_theme_name'] = 'theme' . $i;
Replace them with:
$context['new_theme_name'] = '';
$context['new_light_variant'] = '';
$context['new_besocial_variant'] = '';
2. In the same file, find:
// Install from another directory
Replace them with:
// Copy the default light variant?
elseif (!empty($_REQUEST['copylight'] or $_REQUEST['copybesocial']) && $method == 'copy')
{
// Hopefully the css directory is writable, or we might have a problem.
DEFINE('CSSDIR', BOARDDIR . '/themes/default/css');
if (!is_writable(CSSDIR))
fatal_lang_error('theme_install_write_error', 'critical');
// Make the new directory, standard characters only
if (!empty($_REQUEST['copylight']))
$theme_dir = CSSDIR . '/_' . preg_replace('~[^A-Za-z0-9_\- ]~', '', $_REQUEST['copylight']);
elseif (!empty($_REQUEST['copybesocial']))
$theme_dir = CSSDIR . '/_' . preg_replace('~[^A-Za-z0-9_\- ]~', '', $_REQUEST['copybesocial']);
umask(0);
mkdir($theme_dir, 0777);
// Get some more time if we can
@set_time_limit(600);
if (function_exists('apache_reset_timeout'))
@apache_reset_timeout();
// And now the entire css, images and webfonts directories!
if (!empty($_REQUEST['copylight']))
copytree($settings['default_theme_dir'] . '/css/_light', $theme_dir);
elseif (!empty($_REQUEST['copybesocial']))
copytree($settings['default_theme_dir'] . '/css/_besocial', $theme_dir);
package_flush_cache();
}
// Install from another directory
3. Still in the same file, find:
// Defaults.
$install_info = array(
'theme_url' => $boardurl . '/themes/' . basename($theme_dir),
'images_url' => isset($images_url) ? $images_url : $boardurl . '/themes/' . basename($theme_dir) . '/images',
'theme_dir' => $theme_dir,
'name' => $theme_name
);
Replace them with:
if (!empty($_REQUEST['copylight'] or $_REQUEST['copybesocial'])) {
$install_info = array();
} else {
// Defaults.
$install_info = array(
'theme_url' => $boardurl . '/themes/' . basename($theme_dir),
'images_url' => isset($images_url) ? $images_url : $boardurl . '/themes/' . basename($theme_dir) . '/images',
'theme_dir' => $theme_dir,
'name' => $theme_name
);
}
4. Now open its template file, ManageThemes.template.php, find:
echo '
</dl>
<input type="submit" name="save" value="', $txt['theme_install_go'], '" class="right_submit" />
Replace them with:
if ($context['can_create_new'])
echo '
<dt>
<label for="copy">Copy default theme light variant</label>
</dt>
<dd>
<input type="text" name="copylight" id="copylight" value="', $context['new_light_variant'], '" size="40" class="input_text" />
</dd>';
if ($context['can_create_new'])
echo '
<dt>
<label for="copy">Copy default theme besocial variant</label>
</dt>
<dd>
<input type="text" name="copybesocial" id="copybesocial" value="', $context['new_besocial_variant'], '" size="40" class="input_text" />
</dd>';
echo '
</dl>
<input type="submit" name="save" value="', $txt['theme_install_go'], '" class="right_submit" />
5. In the same file, find:
<a href="', $scripturl, '?action=admin;area=theme;sa=list;th=', $context['installed_theme']['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $context['installed_theme']['name'], '</a> ', $txt['theme_installed_message'], '
Replace them with:
<a href="', $scripturl, '?action=admin;area=theme;sa=list;th=', $context['installed_theme']['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $context['installed_theme']['name'], '</a>
', empty($context['installed_theme']['name']) ? 'A new variant was installed to default theme.' : $txt['theme_installed_message'], '
I tested them in 1.0.9 with no errors, so far but will need to add some $txt to language files, for localisation. Expert opinion is needed though, for feedback, security, improvement, etc.
I guess I forgot to mention that the files name aren't not changed via this mod. I am trying to figure out how to change them, managed to do some renaming but I am stucked when the renamed files became empty, yet the original transferred files are still in the new variant folder.
The above code #2, which are these parts:
// And now the entire css, images and webfonts directories!
if (!empty($_REQUEST['copylight']))
copytree($settings['default_theme_dir'] . '/css/_light', $theme_dir);
elseif (!empty($_REQUEST['copybesocial']))
copytree($settings['default_theme_dir'] . '/css/_besocial', $theme_dir);
package_flush_cache();
They are changed to these:
// And now copy the entire directories!
if (!empty($_REQUEST['copylight'])) {
$new_variant = $_REQUEST['copylight'];
copytree($settings['default_theme_dir'] . '/css/_light', $theme_dir);
foreach (array_filter(glob($theme_dir . "/*.css"), "is_file") as $file) {
$f = realpath($file);
rename ($f, str_replace("light", "$new_variant", $f));
}
} elseif (!empty($_REQUEST['copybesocial'])) {
$new_variant = $_REQUEST['copybesocial'];
copytree($settings['default_theme_dir'] . '/css/_besocial', $theme_dir);
foreach (array_filter(glob($theme_dir . "/*.css"), "is_file") as $file) {
$f = realpath($file);
rename ($f, str_replace("besocial", "$new_variant", $f));
}
}
package_flush_cache();
The *_new_variant.css are there but are all empty. The *_besocial.css or *_light.css are also there in the same new variant folder, unchanged. Strange. ::)
Oh goody. Themes in the db. vB all over again. :P
Elk needz "Do not like" button.
The above mod doesn't put it in db though. Still figuring out why the rename code is not working. The folder and files are both rewritable. Sighed
I think I kinda fix this i.e. properly create folder, copy and rename files, and set proper files and directory permissions. Find the changed code #2, in reply 3, to these:
elseif (!empty($_REQUEST['copylight'] or $_REQUEST['copybesocial']) && $method == 'copy')
{
// Hopefully the css directory is writable, or we might have a problem.
DEFINE('CSSDIR', BOARDDIR . '/themes/default/css');
if (!is_writable(CSSDIR))
fatal_lang_error('theme_install_write_error', 'critical');
// Determine the original variant by its request
$oldvar = (!empty($_REQUEST['copylight']) ? 'light' : 'besocial');
$newvar = (!empty($_REQUEST['copylight']) ? $_REQUEST['copylight'] : $_REQUEST['copybesocial']);
// Make the new directory, standard characters only
$theme_dir = CSSDIR . '/_' . preg_replace('~[^A-Za-z0-9_\- ]~', '', $newvar);
umask(0);
mkdir($theme_dir, 0755);
// Get some more time if we can
@set_time_limit(600);
if (function_exists('apache_reset_timeout'))
@apache_reset_timeout();
// Perform copy and rename all files, then flush cache
copy(CSSDIR . '/_' . $oldvar . '/index.php', $theme_dir . '/index.php');
copy(CSSDIR . '/_' . $oldvar . '/index_' . $oldvar . '.css', $theme_dir . '/index_' . $newvar . '.css');
copy(CSSDIR . '/_' . $oldvar . '/admin_' . $oldvar . '.css', $theme_dir . '/admin_' . $newvar . '.css');
copy(CSSDIR . '/_' . $oldvar . '/rtl_' . $oldvar . '.css', $theme_dir . '/rtl_' . $newvar . '.css');
copy(CSSDIR . '/_' . $oldvar . '/jquery.sceditor.elk_wiz_' . $oldvar . '.css', $theme_dir . '/jquery.sceditor.elk_wiz_' . $newvar . '.css');
foreach (array_filter(glob($theme_dir . '/*.*'), 'is_file') as $f)
chmod($f, 0644);
package_flush_cache();
}
// Install from another directory
I will look into auto editing index.template.php, and other related files, if any, to add the new variant, later.
I have been looking into this again and I was wondering whether it is possible for us to use call_integration_hook('integrate_init_theme', array($theme, &$settings)); to add this new default theme variant into the variant list with its language so that we don't have to modify index.template.php and ManageThemes.english.php.
And if possible, how can we make this into a working code with the above - if (!empty($settings['theme_variants'])) { add this new variant into theme variant list && add $txt['variant_$newvar'] = 'Custom ucwords($newvar)'; }
Sorry, I'll have a look at it soonish! :(
No problem and do take your time until Beta 3 is ready (don't forget to fix its upgrade.php so that we can test upgrading 1.0.9 to it as well ;) ).
And when you have time to look at it, in ManageThemes.controller.php, do look into:
// Load the variants separately...
$settings['theme_variants'] = array();
if (file_exists($settings['theme_dir'] . '/index.template.php'))
{
$file_contents = implode("\n", file($settings['theme_dir'] . '/index.template.php'));
if (preg_match('~\'theme_variants\'\s*=>(.+?\)),$~sm', $file_contents, $matches))
eval('global $settings; $settings[\'theme_variants\'] = ' . $matches[1] . ';');
call_integration_hook('integrate_init_theme', array($theme, &$settings));
}
Currently, based on the above, it seems that we depend on index.template.php for variant list which can also be obtained via css directory something like:
foreach (glob(CSSDIR . '/_*') as $_variant)
if (is_dir($_variant) && !in_array($_variant, array('.', '..')))
$variant = str_replace('_', '', $_variant);
Just a thought that crosses my mind. :)
I don't see this feature being added to 1.1RC2, so does it mean this is already dropped out of 1.1?
Anyway, I created an addon based on the above with minor improvement. It is still in alpha stage and can be obtained from
here (http://www.elkarte.net/community/index.php?topic=4679.0).
I think something like this would fit a general review of the themeing system in order to remove some oddities here and there.
For 2.0 would be a very good point to have IMO.