This is my proposal on implementing the ability to switch frontend and backend templates independently.

- This introduces a new option "template_backend" that will be set to indicate the backend template, defaults to 2k11.
- The "Engine: xxx" line in info.txt still works, but only for the frontend
- The frontend fallback chain defaults to the old "default" template to ensure that themes will work that have "old-style" HTML output
- The backend fallback chain only falls back to 2k11 and then "default"
- In the future, we will remove templates/default/admin once the mechanism is proven stable

To test this in all cases you can:

- Copy 2k11/ to 2k11-custom, edit info.txt, give it a distinct name. Edit the admin/index.tpl file to add some code to ensure that you will see that template in the backend if you pick it, or adjust the style.css or whatever.
- Copy idea/ to idea-custom, edit info.txt, add a "Engine: 2k11" line. Now you can test how a template would look like that fallsback on 2k11 instead of "default"

Those permutations can be checked and come to my mind:

- Backend: 2k11, Frontend: 2k11
- Backend: 2k11-custom, Frontend: 2k11
- Backend: 2k11, Frontend: 2k11-custom

- Backend: 2k11, Frontend: idea
- Backend: 2k11, Frontend: idea-custom

- Backend: 2k11-custom, Frontend: idea
- Backend: 2k11-custom, Frontend: idea-custom

They seem to work.

Currently the display of backend and frontend theme in templates.inc.tpl takes up some larger space. Maybe it could be prettified somehow, maybe put frontend and backend template next to each other, not beneath each other? Maybe @yellowled has some suggestions.

@onli and @ophian - please have a look at this, since you both also worked on the fallback chains. Please tell me if you have issues with this. We can easily revert, if you see this approach as not workable. This is more a "proof of concept" draft.
This commit is contained in:
Garvin Hicking
2014-05-14 12:58:06 +02:00
parent a6b20ad398
commit dd83225447
12 changed files with 143 additions and 27 deletions
+16 -9
View File
@@ -62,7 +62,7 @@ if ($serendipity['GET']['adminAction'] == 'editConfiguration') {
$data["adminAction"] = "editConfiguration";
}
if ($serendipity['GET']['adminAction'] == 'install' ) {
if ($serendipity['GET']['adminAction'] == 'install' || $serendipity['GET']['adminAction'] == 'install-frontend' || $serendipity['GET']['adminAction'] == 'install-backend') {
serendipity_plugin_api::hook_event('backend_templates_fetchtemplate', $serendipity);
$themeInfo = serendipity_fetchTemplateInfo(htmlspecialchars($serendipity['GET']['theme']));
@@ -70,25 +70,32 @@ if ($serendipity['GET']['adminAction'] == 'install' ) {
// A separate hook is used post installation, for plugins to possibly perform some actions
serendipity_plugin_api::hook_event('backend_templates_install', $serendipity['GET']['theme'], $themeInfo);
serendipity_set_config_var('template', htmlspecialchars($serendipity['GET']['theme']));
if ($serendipity['GET']['adminAction'] == 'install' || $serendipity['GET']['adminAction'] == 'install-frontend') {
serendipity_set_config_var('template', htmlspecialchars($serendipity['GET']['theme']));
}
// template_engine was set by default to default, which screws up the fallback chain (to the default-template first)
serendipity_set_config_var('template_engine', null);
if ($themeInfo['engine']) {
serendipity_set_config_var('template_engine', $themeInfo['engine']);
if ($serendipity['GET']['adminAction'] == 'install-backend' && $themeInfo['custom_admin_interface'] == YES) {
serendipity_set_config_var('template_backend', htmlspecialchars($serendipity['GET']['theme']));
} else {
// template_engine was set by default to default, which screws up the fallback chain (to the default-template first)
// The "Engine" now only applies to FRONTEND themes. Backend themes will always fall back to our default backend theme only, to ensure proper backend operation.
serendipity_set_config_var('template_engine', null);
if ($themeInfo['engine']) {
serendipity_set_config_var('template_engine', $themeInfo['engine']);
}
}
serendipity_set_config_var('last_template_change', time());
$data["adminAction"] = "install";
$data["install_template"] = htmlspecialchars($serendipity['GET']['theme']);
}
if ( @file_exists($serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['template'] .'/layout.php') ) {
$data["deprecated"] = true;
}
$data["cur_template"] = $serendipity['template'];
$data["cur_template"] = $serendipity['template'];
$data["cur_template_backend"] = $serendipity['template_backend'];
if (file_exists($serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['template'] . '/config.inc.php')) {
serendipity_smarty_init();
@@ -201,4 +208,4 @@ foreach ($stack as $theme => $info) {
echo serendipity_smarty_show('admin/templates.inc.tpl', $data);
/* vim: set sts=4 ts=4 expandtab : */
/* vim: set sts=4 ts=4 expandtab : */
+1 -1
View File
@@ -260,7 +260,7 @@ function serendipity_fetchTemplateInfo($theme, $abspath = null) {
if ( $theme != 'default' && $theme != 'default-rtl'
&& @is_dir($serendipity['templatePath'] . $theme . '/admin')
&& @is_readable($serendipity['templatePath'] . $theme . '/admin/style.css') ) {
&& strtolower($data['backend']) == 'yes' ) {
$data['custom_admin_interface'] = YES;
} else {
+19 -9
View File
@@ -261,16 +261,26 @@ function serendipity_getTemplateFile($file, $key = 'serendipityHTTPPath') {
$directories = array();
$directories[] = isset($serendipity['template']) ? $serendipity['template'] . '/' : '';
if (isset($serendipity['template_engine']) && $serendipity['template_engine'] != null) {
$p = explode(',', $serendipity['template_engine']);
foreach($p AS $te) {
$directories[] = trim($te) . '/';
if (defined('IN_serendipity_admin')) {
// Backend will always use our default backend (=defaultTemplate) as fallback.
$directories[] = isset($serendipity['template_backend']) ? $serendipity['template_backend'] . '/' : '';
$directories[] = $serendipity['defaultTemplate'] .'/';
$directories[] = 'default/';
} else {
$directories[] = isset($serendipity['template']) ? $serendipity['template'] . '/' : '';
if (isset($serendipity['template_engine']) && $serendipity['template_engine'] != null) {
$p = explode(',', $serendipity['template_engine']);
foreach($p AS $te) {
$directories[] = trim($te) . '/';
}
}
}
$directories[] = $serendipity['defaultTemplate'] .'/';
$directories[] = 'default/';
// Frontend templates currently need to fall back to "default" (see "idea"), so that they get the
// output they desire. If templates are based on 2k11, the need to set "Engine: 2k11" in their info.txt
// file.
$directories[] = 'default/';
$directories[] = $serendipity['defaultTemplate'] .'/';
}
foreach ($directories as $directory) {
$templateFile = $serendipity['templatePath'] . $directory . $file;
@@ -279,7 +289,7 @@ function serendipity_getTemplateFile($file, $key = 'serendipityHTTPPath') {
}
if (file_exists($serendipity['serendipityPath'] . $templateFile . ".tpl") && $serendipity['template'] . '/' == $directory && IS_installed) {
# catch .js.tpl files served via the template-plugin-api, but only if that template is active as well, so config.inc.php is laoded
# catch .js.tpl files served via the template-plugin-api, but only if that template is active as well, so config.inc.php is loaded
# this won't work in the installer
return $serendipity['baseURL'] . 'index.php?/plugin/' . $file;
}
+23 -1
View File
@@ -864,6 +864,12 @@ function serendipity_smarty_init($vars = array()) {
// Beware: Smarty is used in the Admin backend, despite of this.
include_once $template_dir . '/template.inc.php';
} else {
// Backend template overwritten here (NOT earlier due to frontend specific check
if (defined('IN_serendipity_admin')) {
$template_dir = $serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['template_backend'];
}
// Set a session variable if Smarty fails:
$prev_smarty = $_SESSION['no_smarty'];
$_SESSION['no_smarty'] = true;
@@ -1014,6 +1020,7 @@ function serendipity_smarty_init($vars = array()) {
'category' => $category,
'category_info' => $category_info,
'template' => $serendipity['template'],
'template_backend' => $serendipity['template_backend'],
'dateRange' => (!empty($serendipity['range']) ? $serendipity['range'] : array())
)
@@ -1025,11 +1032,26 @@ function serendipity_smarty_init($vars = array()) {
// For advanced usage, we allow template authors to create a file 'config.inc.php' where they can
// setup custom smarty variables, modifiers etc. to use in their templates.
// If a template engine is defined we need that config.inc.php file as well. The template's actual file is loaded after that to be able to overwrite config.
if (isset($serendipity['template_engine']) && $serendipity['template_engine'] != null) {
$p = explode(',', $serendipity['template_engine']);
foreach($p AS $te) {
$config = $serendipity['serendipityPath'] . $serendipity['templatePath'] . trim($te) . '/config.inc.php';
if (file_exists($config)) {
include_once $config;
}
}
}
$config = $serendipity['smarty']->getConfigDir(0) . '/config.inc.php';
if (file_exists($config)) {
include_once $config;
}
if (is_array($template_loaded_config)) {
$template_vars =& $template_loaded_config;
$serendipity['smarty']->assignByRef('template_option', $template_vars);
+6
View File
@@ -18,9 +18,15 @@ if (!defined('serendipity_LANG_LOADED') || serendipity_LANG_LOADED !== true) {
if (defined('S9Y_DATA_PATH')) {
@include_once (S9Y_DATA_PATH . 'templates/' . $serendipity['template'] . '/' . $charset . 'lang_' . $serendipity['lang'] . '.inc.php');
@include_once (S9Y_DATA_PATH . 'templates/' . $serendipity['template'] . '/lang_en.inc.php');
@include_once (S9Y_DATA_PATH . 'templates/' . $serendipity['template_backend'] . '/' . $charset . 'lang_' . $serendipity['lang'] . '.inc.php');
@include_once (S9Y_DATA_PATH . 'templates/' . $serendipity['template_backend'] . '/lang_en.inc.php');
} else {
@include_once (S9Y_INCLUDE_PATH . 'templates/' . $serendipity['template'] . '/' . $charset . 'lang_' . $serendipity['lang'] . '.inc.php');
@include_once (S9Y_INCLUDE_PATH . 'templates/' . $serendipity['template'] . '/lang_en.inc.php');
@include_once (S9Y_INCLUDE_PATH . 'templates/' . $serendipity['template_backend'] . '/' . $charset . 'lang_' . $serendipity['lang'] . '.inc.php');
@include_once (S9Y_INCLUDE_PATH . 'templates/' . $serendipity['template_backend'] . '/lang_en.inc.php');
}
}
+10 -3
View File
@@ -4,6 +4,7 @@
// define secure_dir and trusted_dirs for Serendipity_Smarty_Security_Policy class.
@define('S9Y_TEMPLATE_FALLBACK', $serendipity['serendipityPath'] . $serendipity['templatePath'] . 'default');
@define('S9Y_TEMPLATE_USERDEFAULT', $serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['template']);
@define('S9Y_TEMPLATE_USERDEFAULT_BACKEND', $serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['template_backend']);
@define('S9Y_TEMPLATE_SECUREDIR', $serendipity['serendipityPath'] . $serendipity['templatePath']);
@@ -29,7 +30,7 @@ class Serendipity_Smarty_Security_Policy extends Smarty_Security
public $secure_dir = array(S9Y_TEMPLATE_SECUREDIR); // do we need this then?
// actually no need, as template dirs are explicit defined as trusted_dirs. (unproofed)
public $trusted_dir = array(S9Y_TEMPLATE_USERDEFAULT, S9Y_TEMPLATE_FALLBACK); // do we need this then?
public $trusted_dir = array(S9Y_TEMPLATE_USERDEFAULT, S9Y_TEMPLATE_USERDEFAULT_BACKEND, S9Y_TEMPLATE_FALLBACK); // do we need this then?
#public $modifiers = array(); // can be omitted, when all allowed
@@ -121,9 +122,15 @@ class Serendipity_Smarty extends Smarty
$template_engine = serendipity_get_config_var('template_engine');
$template_dirs = array();
if ($template_engine) {
$template_dirs[] = $serendipity['serendipityPath'] . $serendipity['templatePath'] . $template_engine;
}
$p = explode(',', $template_engine);
foreach($p AS $te) {
$template_dirs[] = $serendipity['serendipityPath'] . $serendipity['templatePath'] . trim($te) . '/';
}
}
$template_dirs[] = $serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['defaultTemplate'];
$template_dirs[] = $serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['template_backend'];
// add secure dir to template path, in case engine did have entries
if (S9Y_TEMPLATE_SECUREDIR != $serendipity['serendipityPath'] . $serendipity['templatePath']) {
$template_dirs[] = S9Y_TEMPLATE_SECUREDIR;